1 //===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the main API hooks in the Clang-C Source Indexing
10 // library.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "CIndexDiagnostic.h"
15 #include "CIndexer.h"
16 #include "CLog.h"
17 #include "CXCursor.h"
18 #include "CXSourceLocation.h"
19 #include "CXString.h"
20 #include "CXTranslationUnit.h"
21 #include "CXType.h"
22 #include "CursorVisitor.h"
23 #include "clang-c/FatalErrorHandler.h"
24 #include "clang/AST/Attr.h"
25 #include "clang/AST/DeclObjCCommon.h"
26 #include "clang/AST/Mangle.h"
27 #include "clang/AST/OpenMPClause.h"
28 #include "clang/AST/StmtVisitor.h"
29 #include "clang/Basic/Diagnostic.h"
30 #include "clang/Basic/DiagnosticCategories.h"
31 #include "clang/Basic/DiagnosticIDs.h"
32 #include "clang/Basic/Stack.h"
33 #include "clang/Basic/TargetInfo.h"
34 #include "clang/Basic/Version.h"
35 #include "clang/Frontend/ASTUnit.h"
36 #include "clang/Frontend/CompilerInstance.h"
37 #include "clang/Index/CommentToXML.h"
38 #include "clang/Lex/HeaderSearch.h"
39 #include "clang/Lex/Lexer.h"
40 #include "clang/Lex/PreprocessingRecord.h"
41 #include "clang/Lex/Preprocessor.h"
42 #include "llvm/ADT/Optional.h"
43 #include "llvm/ADT/STLExtras.h"
44 #include "llvm/ADT/StringSwitch.h"
45 #include "llvm/Config/llvm-config.h"
46 #include "llvm/Support/Compiler.h"
47 #include "llvm/Support/CrashRecoveryContext.h"
48 #include "llvm/Support/Format.h"
49 #include "llvm/Support/ManagedStatic.h"
50 #include "llvm/Support/MemoryBuffer.h"
51 #include "llvm/Support/Program.h"
52 #include "llvm/Support/SaveAndRestore.h"
53 #include "llvm/Support/Signals.h"
54 #include "llvm/Support/TargetSelect.h"
55 #include "llvm/Support/Threading.h"
56 #include "llvm/Support/Timer.h"
57 #include "llvm/Support/raw_ostream.h"
58 #include "llvm/Support/thread.h"
59 #include <mutex>
60
61 #if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62 #define USE_DARWIN_THREADS
63 #endif
64
65 #ifdef USE_DARWIN_THREADS
66 #include <pthread.h>
67 #endif
68
69 using namespace clang;
70 using namespace clang::cxcursor;
71 using namespace clang::cxtu;
72 using namespace clang::cxindex;
73
MakeCXTranslationUnit(CIndexer * CIdx,std::unique_ptr<ASTUnit> AU)74 CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,
75 std::unique_ptr<ASTUnit> AU) {
76 if (!AU)
77 return nullptr;
78 assert(CIdx);
79 CXTranslationUnit D = new CXTranslationUnitImpl();
80 D->CIdx = CIdx;
81 D->TheASTUnit = AU.release();
82 D->StringPool = new cxstring::CXStringPool();
83 D->Diagnostics = nullptr;
84 D->OverridenCursorsPool = createOverridenCXCursorsPool();
85 D->CommentToXML = nullptr;
86 D->ParsingOptions = 0;
87 D->Arguments = {};
88 return D;
89 }
90
isASTReadError(ASTUnit * AU)91 bool cxtu::isASTReadError(ASTUnit *AU) {
92 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
93 DEnd = AU->stored_diag_end();
94 D != DEnd; ++D) {
95 if (D->getLevel() >= DiagnosticsEngine::Error &&
96 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
97 diag::DiagCat_AST_Deserialization_Issue)
98 return true;
99 }
100 return false;
101 }
102
~CXTUOwner()103 cxtu::CXTUOwner::~CXTUOwner() {
104 if (TU)
105 clang_disposeTranslationUnit(TU);
106 }
107
108 /// Compare two source ranges to determine their relative position in
109 /// the translation unit.
RangeCompare(SourceManager & SM,SourceRange R1,SourceRange R2)110 static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1,
111 SourceRange R2) {
112 assert(R1.isValid() && "First range is invalid?");
113 assert(R2.isValid() && "Second range is invalid?");
114 if (R1.getEnd() != R2.getBegin() &&
115 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
116 return RangeBefore;
117 if (R2.getEnd() != R1.getBegin() &&
118 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
119 return RangeAfter;
120 return RangeOverlap;
121 }
122
123 /// Determine if a source location falls within, before, or after a
124 /// a given source range.
LocationCompare(SourceManager & SM,SourceLocation L,SourceRange R)125 static RangeComparisonResult LocationCompare(SourceManager &SM,
126 SourceLocation L, SourceRange R) {
127 assert(R.isValid() && "First range is invalid?");
128 assert(L.isValid() && "Second range is invalid?");
129 if (L == R.getBegin() || L == R.getEnd())
130 return RangeOverlap;
131 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
132 return RangeBefore;
133 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
134 return RangeAfter;
135 return RangeOverlap;
136 }
137
138 /// Translate a Clang source range into a CIndex source range.
139 ///
140 /// Clang internally represents ranges where the end location points to the
141 /// start of the token at the end. However, for external clients it is more
142 /// useful to have a CXSourceRange be a proper half-open interval. This routine
143 /// does the appropriate translation.
translateSourceRange(const SourceManager & SM,const LangOptions & LangOpts,const CharSourceRange & R)144 CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
145 const LangOptions &LangOpts,
146 const CharSourceRange &R) {
147 // We want the last character in this location, so we will adjust the
148 // location accordingly.
149 SourceLocation EndLoc = R.getEnd();
150 bool IsTokenRange = R.isTokenRange();
151 if (EndLoc.isValid() && EndLoc.isMacroID() &&
152 !SM.isMacroArgExpansion(EndLoc)) {
153 CharSourceRange Expansion = SM.getExpansionRange(EndLoc);
154 EndLoc = Expansion.getEnd();
155 IsTokenRange = Expansion.isTokenRange();
156 }
157 if (IsTokenRange && EndLoc.isValid()) {
158 unsigned Length =
159 Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);
160 EndLoc = EndLoc.getLocWithOffset(Length);
161 }
162
163 CXSourceRange Result = {
164 {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};
165 return Result;
166 }
167
translateCXRangeToCharRange(CXSourceRange R)168 CharSourceRange cxloc::translateCXRangeToCharRange(CXSourceRange R) {
169 return CharSourceRange::getCharRange(
170 SourceLocation::getFromRawEncoding(R.begin_int_data),
171 SourceLocation::getFromRawEncoding(R.end_int_data));
172 }
173
174 //===----------------------------------------------------------------------===//
175 // Cursor visitor.
176 //===----------------------------------------------------------------------===//
177
178 static SourceRange getRawCursorExtent(CXCursor C);
179 static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
180
CompareRegionOfInterest(SourceRange R)181 RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
182 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
183 }
184
185 /// Visit the given cursor and, if requested by the visitor,
186 /// its children.
187 ///
188 /// \param Cursor the cursor to visit.
189 ///
190 /// \param CheckedRegionOfInterest if true, then the caller already checked
191 /// that this cursor is within the region of interest.
192 ///
193 /// \returns true if the visitation should be aborted, false if it
194 /// should continue.
Visit(CXCursor Cursor,bool CheckedRegionOfInterest)195 bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
196 if (clang_isInvalid(Cursor.kind))
197 return false;
198
199 if (clang_isDeclaration(Cursor.kind)) {
200 const Decl *D = getCursorDecl(Cursor);
201 if (!D) {
202 assert(0 && "Invalid declaration cursor");
203 return true; // abort.
204 }
205
206 // Ignore implicit declarations, unless it's an objc method because
207 // currently we should report implicit methods for properties when indexing.
208 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
209 return false;
210 }
211
212 // If we have a range of interest, and this cursor doesn't intersect with it,
213 // we're done.
214 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
215 SourceRange Range = getRawCursorExtent(Cursor);
216 if (Range.isInvalid() || CompareRegionOfInterest(Range))
217 return false;
218 }
219
220 switch (Visitor(Cursor, Parent, ClientData)) {
221 case CXChildVisit_Break:
222 return true;
223
224 case CXChildVisit_Continue:
225 return false;
226
227 case CXChildVisit_Recurse: {
228 bool ret = VisitChildren(Cursor);
229 if (PostChildrenVisitor)
230 if (PostChildrenVisitor(Cursor, ClientData))
231 return true;
232 return ret;
233 }
234 }
235
236 llvm_unreachable("Invalid CXChildVisitResult!");
237 }
238
visitPreprocessedEntitiesInRange(SourceRange R,PreprocessingRecord & PPRec,CursorVisitor & Visitor)239 static bool visitPreprocessedEntitiesInRange(SourceRange R,
240 PreprocessingRecord &PPRec,
241 CursorVisitor &Visitor) {
242 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
243 FileID FID;
244
245 if (!Visitor.shouldVisitIncludedEntities()) {
246 // If the begin/end of the range lie in the same FileID, do the optimization
247 // where we skip preprocessed entities that do not come from the same
248 // FileID.
249 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
250 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
251 FID = FileID();
252 }
253
254 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
255 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
256 PPRec, FID);
257 }
258
visitFileRegion()259 bool CursorVisitor::visitFileRegion() {
260 if (RegionOfInterest.isInvalid())
261 return false;
262
263 ASTUnit *Unit = cxtu::getASTUnit(TU);
264 SourceManager &SM = Unit->getSourceManager();
265
266 std::pair<FileID, unsigned> Begin = SM.getDecomposedLoc(
267 SM.getFileLoc(RegionOfInterest.getBegin())),
268 End = SM.getDecomposedLoc(
269 SM.getFileLoc(RegionOfInterest.getEnd()));
270
271 if (End.first != Begin.first) {
272 // If the end does not reside in the same file, try to recover by
273 // picking the end of the file of begin location.
274 End.first = Begin.first;
275 End.second = SM.getFileIDSize(Begin.first);
276 }
277
278 assert(Begin.first == End.first);
279 if (Begin.second > End.second)
280 return false;
281
282 FileID File = Begin.first;
283 unsigned Offset = Begin.second;
284 unsigned Length = End.second - Begin.second;
285
286 if (!VisitDeclsOnly && !VisitPreprocessorLast)
287 if (visitPreprocessedEntitiesInRegion())
288 return true; // visitation break.
289
290 if (visitDeclsFromFileRegion(File, Offset, Length))
291 return true; // visitation break.
292
293 if (!VisitDeclsOnly && VisitPreprocessorLast)
294 return visitPreprocessedEntitiesInRegion();
295
296 return false;
297 }
298
isInLexicalContext(Decl * D,DeclContext * DC)299 static bool isInLexicalContext(Decl *D, DeclContext *DC) {
300 if (!DC)
301 return false;
302
303 for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;
304 DeclDC = DeclDC->getLexicalParent()) {
305 if (DeclDC == DC)
306 return true;
307 }
308 return false;
309 }
310
visitDeclsFromFileRegion(FileID File,unsigned Offset,unsigned Length)311 bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,
312 unsigned Length) {
313 ASTUnit *Unit = cxtu::getASTUnit(TU);
314 SourceManager &SM = Unit->getSourceManager();
315 SourceRange Range = RegionOfInterest;
316
317 SmallVector<Decl *, 16> Decls;
318 Unit->findFileRegionDecls(File, Offset, Length, Decls);
319
320 // If we didn't find any file level decls for the file, try looking at the
321 // file that it was included from.
322 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
323 bool Invalid = false;
324 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
325 if (Invalid)
326 return false;
327
328 SourceLocation Outer;
329 if (SLEntry.isFile())
330 Outer = SLEntry.getFile().getIncludeLoc();
331 else
332 Outer = SLEntry.getExpansion().getExpansionLocStart();
333 if (Outer.isInvalid())
334 return false;
335
336 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
337 Length = 0;
338 Unit->findFileRegionDecls(File, Offset, Length, Decls);
339 }
340
341 assert(!Decls.empty());
342
343 bool VisitedAtLeastOnce = false;
344 DeclContext *CurDC = nullptr;
345 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
346 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
347 Decl *D = *DIt;
348 if (D->getSourceRange().isInvalid())
349 continue;
350
351 if (isInLexicalContext(D, CurDC))
352 continue;
353
354 CurDC = dyn_cast<DeclContext>(D);
355
356 if (TagDecl *TD = dyn_cast<TagDecl>(D))
357 if (!TD->isFreeStanding())
358 continue;
359
360 RangeComparisonResult CompRes =
361 RangeCompare(SM, D->getSourceRange(), Range);
362 if (CompRes == RangeBefore)
363 continue;
364 if (CompRes == RangeAfter)
365 break;
366
367 assert(CompRes == RangeOverlap);
368 VisitedAtLeastOnce = true;
369
370 if (isa<ObjCContainerDecl>(D)) {
371 FileDI_current = &DIt;
372 FileDE_current = DE;
373 } else {
374 FileDI_current = nullptr;
375 }
376
377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
379 }
380
381 if (VisitedAtLeastOnce)
382 return false;
383
384 // No Decls overlapped with the range. Move up the lexical context until there
385 // is a context that contains the range or we reach the translation unit
386 // level.
387 DeclContext *DC = DIt == Decls.begin()
388 ? (*DIt)->getLexicalDeclContext()
389 : (*(DIt - 1))->getLexicalDeclContext();
390
391 while (DC && !DC->isTranslationUnit()) {
392 Decl *D = cast<Decl>(DC);
393 SourceRange CurDeclRange = D->getSourceRange();
394 if (CurDeclRange.isInvalid())
395 break;
396
397 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
398 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
399 return true; // visitation break.
400 }
401
402 DC = D->getLexicalDeclContext();
403 }
404
405 return false;
406 }
407
visitPreprocessedEntitiesInRegion()408 bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
409 if (!AU->getPreprocessor().getPreprocessingRecord())
410 return false;
411
412 PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();
413 SourceManager &SM = AU->getSourceManager();
414
415 if (RegionOfInterest.isValid()) {
416 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
417 SourceLocation B = MappedRange.getBegin();
418 SourceLocation E = MappedRange.getEnd();
419
420 if (AU->isInPreambleFileID(B)) {
421 if (SM.isLoadedSourceLocation(E))
422 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,
423 *this);
424
425 // Beginning of range lies in the preamble but it also extends beyond
426 // it into the main file. Split the range into 2 parts, one covering
427 // the preamble and another covering the main file. This allows subsequent
428 // calls to visitPreprocessedEntitiesInRange to accept a source range that
429 // lies in the same FileID, allowing it to skip preprocessed entities that
430 // do not come from the same FileID.
431 bool breaked = visitPreprocessedEntitiesInRange(
432 SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);
433 if (breaked)
434 return true;
435 return visitPreprocessedEntitiesInRange(
436 SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);
437 }
438
439 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
440 }
441
442 bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
443
444 if (OnlyLocalDecls)
445 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
446 PPRec);
447
448 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
449 }
450
451 template <typename InputIterator>
visitPreprocessedEntities(InputIterator First,InputIterator Last,PreprocessingRecord & PPRec,FileID FID)452 bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
453 InputIterator Last,
454 PreprocessingRecord &PPRec,
455 FileID FID) {
456 for (; First != Last; ++First) {
457 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
458 continue;
459
460 PreprocessedEntity *PPE = *First;
461 if (!PPE)
462 continue;
463
464 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
465 if (Visit(MakeMacroExpansionCursor(ME, TU)))
466 return true;
467
468 continue;
469 }
470
471 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
472 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
473 return true;
474
475 continue;
476 }
477
478 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
479 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
480 return true;
481
482 continue;
483 }
484 }
485
486 return false;
487 }
488
489 /// Visit the children of the given cursor.
490 ///
491 /// \returns true if the visitation should be aborted, false if it
492 /// should continue.
VisitChildren(CXCursor Cursor)493 bool CursorVisitor::VisitChildren(CXCursor Cursor) {
494 if (clang_isReference(Cursor.kind) &&
495 Cursor.kind != CXCursor_CXXBaseSpecifier) {
496 // By definition, references have no children.
497 return false;
498 }
499
500 // Set the Parent field to Cursor, then back to its old value once we're
501 // done.
502 SetParentRAII SetParent(Parent, StmtParent, Cursor);
503
504 if (clang_isDeclaration(Cursor.kind)) {
505 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
506 if (!D)
507 return false;
508
509 return VisitAttributes(D) || Visit(D);
510 }
511
512 if (clang_isStatement(Cursor.kind)) {
513 if (const Stmt *S = getCursorStmt(Cursor))
514 return Visit(S);
515
516 return false;
517 }
518
519 if (clang_isExpression(Cursor.kind)) {
520 if (const Expr *E = getCursorExpr(Cursor))
521 return Visit(E);
522
523 return false;
524 }
525
526 if (clang_isTranslationUnit(Cursor.kind)) {
527 CXTranslationUnit TU = getCursorTU(Cursor);
528 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
529
530 int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
531 for (unsigned I = 0; I != 2; ++I) {
532 if (VisitOrder[I]) {
533 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
534 RegionOfInterest.isInvalid()) {
535 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
536 TLEnd = CXXUnit->top_level_end();
537 TL != TLEnd; ++TL) {
538 const Optional<bool> V = handleDeclForVisitation(*TL);
539 if (!V.hasValue())
540 continue;
541 return V.getValue();
542 }
543 } else if (VisitDeclContext(
544 CXXUnit->getASTContext().getTranslationUnitDecl()))
545 return true;
546 continue;
547 }
548
549 // Walk the preprocessing record.
550 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
551 visitPreprocessedEntitiesInRegion();
552 }
553
554 return false;
555 }
556
557 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
558 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
559 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
560 return Visit(BaseTSInfo->getTypeLoc());
561 }
562 }
563 }
564
565 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
566 const IBOutletCollectionAttr *A =
567 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
568 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
569 return Visit(cxcursor::MakeCursorObjCClassRef(
570 ObjT->getInterface(),
571 A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));
572 }
573
574 // If pointing inside a macro definition, check if the token is an identifier
575 // that was ever defined as a macro. In such a case, create a "pseudo" macro
576 // expansion cursor for that token.
577 SourceLocation BeginLoc = RegionOfInterest.getBegin();
578 if (Cursor.kind == CXCursor_MacroDefinition &&
579 BeginLoc == RegionOfInterest.getEnd()) {
580 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
581 const MacroInfo *MI =
582 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
583 if (MacroDefinitionRecord *MacroDef =
584 checkForMacroInMacroDefinition(MI, Loc, TU))
585 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
586 }
587
588 // Nothing to visit at the moment.
589 return false;
590 }
591
VisitBlockDecl(BlockDecl * B)592 bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
593 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
594 if (Visit(TSInfo->getTypeLoc()))
595 return true;
596
597 if (Stmt *Body = B->getBody())
598 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
599
600 return false;
601 }
602
shouldVisitCursor(CXCursor Cursor)603 Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
604 if (RegionOfInterest.isValid()) {
605 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
606 if (Range.isInvalid())
607 return None;
608
609 switch (CompareRegionOfInterest(Range)) {
610 case RangeBefore:
611 // This declaration comes before the region of interest; skip it.
612 return None;
613
614 case RangeAfter:
615 // This declaration comes after the region of interest; we're done.
616 return false;
617
618 case RangeOverlap:
619 // This declaration overlaps the region of interest; visit it.
620 break;
621 }
622 }
623 return true;
624 }
625
VisitDeclContext(DeclContext * DC)626 bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
627 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
628
629 // FIXME: Eventually remove. This part of a hack to support proper
630 // iteration over all Decls contained lexically within an ObjC container.
631 SaveAndRestore<DeclContext::decl_iterator *> DI_saved(DI_current, &I);
632 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
633
634 for (; I != E; ++I) {
635 Decl *D = *I;
636 if (D->getLexicalDeclContext() != DC)
637 continue;
638 // Filter out synthesized property accessor redeclarations.
639 if (isa<ObjCImplDecl>(DC))
640 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
641 if (OMD->isSynthesizedAccessorStub())
642 continue;
643 const Optional<bool> V = handleDeclForVisitation(D);
644 if (!V.hasValue())
645 continue;
646 return V.getValue();
647 }
648 return false;
649 }
650
handleDeclForVisitation(const Decl * D)651 Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
652 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
653
654 // Ignore synthesized ivars here, otherwise if we have something like:
655 // @synthesize prop = _prop;
656 // and '_prop' is not declared, we will encounter a '_prop' ivar before
657 // encountering the 'prop' synthesize declaration and we will think that
658 // we passed the region-of-interest.
659 if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
660 if (ivarD->getSynthesize())
661 return None;
662 }
663
664 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
665 // declarations is a mismatch with the compiler semantics.
666 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
667 auto *ID = cast<ObjCInterfaceDecl>(D);
668 if (!ID->isThisDeclarationADefinition())
669 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
670
671 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
672 auto *PD = cast<ObjCProtocolDecl>(D);
673 if (!PD->isThisDeclarationADefinition())
674 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
675 }
676
677 const Optional<bool> V = shouldVisitCursor(Cursor);
678 if (!V.hasValue())
679 return None;
680 if (!V.getValue())
681 return false;
682 if (Visit(Cursor, true))
683 return true;
684 return None;
685 }
686
VisitTranslationUnitDecl(TranslationUnitDecl * D)687 bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
688 llvm_unreachable("Translation units are visited directly by Visit()");
689 }
690
VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl * D)691 bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
692 if (VisitTemplateParameters(D->getTemplateParameters()))
693 return true;
694
695 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
696 }
697
VisitTypeAliasDecl(TypeAliasDecl * D)698 bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
699 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
700 return Visit(TSInfo->getTypeLoc());
701
702 return false;
703 }
704
VisitTypedefDecl(TypedefDecl * D)705 bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
706 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
707 return Visit(TSInfo->getTypeLoc());
708
709 return false;
710 }
711
VisitTagDecl(TagDecl * D)712 bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }
713
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)714 bool CursorVisitor::VisitClassTemplateSpecializationDecl(
715 ClassTemplateSpecializationDecl *D) {
716 bool ShouldVisitBody = false;
717 switch (D->getSpecializationKind()) {
718 case TSK_Undeclared:
719 case TSK_ImplicitInstantiation:
720 // Nothing to visit
721 return false;
722
723 case TSK_ExplicitInstantiationDeclaration:
724 case TSK_ExplicitInstantiationDefinition:
725 break;
726
727 case TSK_ExplicitSpecialization:
728 ShouldVisitBody = true;
729 break;
730 }
731
732 // Visit the template arguments used in the specialization.
733 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
734 TypeLoc TL = SpecType->getTypeLoc();
735 if (TemplateSpecializationTypeLoc TSTLoc =
736 TL.getAs<TemplateSpecializationTypeLoc>()) {
737 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
738 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
739 return true;
740 }
741 }
742
743 return ShouldVisitBody && VisitCXXRecordDecl(D);
744 }
745
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)746 bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
747 ClassTemplatePartialSpecializationDecl *D) {
748 // FIXME: Visit the "outer" template parameter lists on the TagDecl
749 // before visiting these template parameters.
750 if (VisitTemplateParameters(D->getTemplateParameters()))
751 return true;
752
753 // Visit the partial specialization arguments.
754 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
755 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
756 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
757 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
758 return true;
759
760 return VisitCXXRecordDecl(D);
761 }
762
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)763 bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
764 if (const auto *TC = D->getTypeConstraint())
765 if (Visit(MakeCXCursor(TC->getImmediatelyDeclaredConstraint(), StmtParent,
766 TU, RegionOfInterest)))
767 return true;
768
769 // Visit the default argument.
770 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
771 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
772 if (Visit(DefArg->getTypeLoc()))
773 return true;
774
775 return false;
776 }
777
VisitEnumConstantDecl(EnumConstantDecl * D)778 bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
779 if (Expr *Init = D->getInitExpr())
780 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
781 return false;
782 }
783
VisitDeclaratorDecl(DeclaratorDecl * DD)784 bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
785 unsigned NumParamList = DD->getNumTemplateParameterLists();
786 for (unsigned i = 0; i < NumParamList; i++) {
787 TemplateParameterList *Params = DD->getTemplateParameterList(i);
788 if (VisitTemplateParameters(Params))
789 return true;
790 }
791
792 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
793 if (Visit(TSInfo->getTypeLoc()))
794 return true;
795
796 // Visit the nested-name-specifier, if present.
797 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
798 if (VisitNestedNameSpecifierLoc(QualifierLoc))
799 return true;
800
801 return false;
802 }
803
HasTrailingReturnType(FunctionDecl * ND)804 static bool HasTrailingReturnType(FunctionDecl *ND) {
805 const QualType Ty = ND->getType();
806 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
807 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
808 return FT->hasTrailingReturn();
809 }
810
811 return false;
812 }
813
814 /// Compare two base or member initializers based on their source order.
CompareCXXCtorInitializers(CXXCtorInitializer * const * X,CXXCtorInitializer * const * Y)815 static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
816 CXXCtorInitializer *const *Y) {
817 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
818 }
819
VisitFunctionDecl(FunctionDecl * ND)820 bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
821 unsigned NumParamList = ND->getNumTemplateParameterLists();
822 for (unsigned i = 0; i < NumParamList; i++) {
823 TemplateParameterList *Params = ND->getTemplateParameterList(i);
824 if (VisitTemplateParameters(Params))
825 return true;
826 }
827
828 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
829 // Visit the function declaration's syntactic components in the order
830 // written. This requires a bit of work.
831 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
832 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
833 const bool HasTrailingRT = HasTrailingReturnType(ND);
834
835 // If we have a function declared directly (without the use of a typedef),
836 // visit just the return type. Otherwise, just visit the function's type
837 // now.
838 if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
839 Visit(FTL.getReturnLoc())) ||
840 (!FTL && Visit(TL)))
841 return true;
842
843 // Visit the nested-name-specifier, if present.
844 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
845 if (VisitNestedNameSpecifierLoc(QualifierLoc))
846 return true;
847
848 // Visit the declaration name.
849 if (!isa<CXXDestructorDecl>(ND))
850 if (VisitDeclarationNameInfo(ND->getNameInfo()))
851 return true;
852
853 // FIXME: Visit explicitly-specified template arguments!
854
855 // Visit the function parameters, if we have a function type.
856 if (FTL && VisitFunctionTypeLoc(FTL, true))
857 return true;
858
859 // Visit the function's trailing return type.
860 if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
861 return true;
862
863 // FIXME: Attributes?
864 }
865
866 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
867 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
868 // Find the initializers that were written in the source.
869 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
870 for (auto *I : Constructor->inits()) {
871 if (!I->isWritten())
872 continue;
873
874 WrittenInits.push_back(I);
875 }
876
877 // Sort the initializers in source order
878 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
879 &CompareCXXCtorInitializers);
880
881 // Visit the initializers in source order
882 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
883 CXXCtorInitializer *Init = WrittenInits[I];
884 if (Init->isAnyMemberInitializer()) {
885 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
886 Init->getMemberLocation(), TU)))
887 return true;
888 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
889 if (Visit(TInfo->getTypeLoc()))
890 return true;
891 }
892
893 // Visit the initializer value.
894 if (Expr *Initializer = Init->getInit())
895 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
896 return true;
897 }
898 }
899
900 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
901 return true;
902 }
903
904 return false;
905 }
906
VisitFieldDecl(FieldDecl * D)907 bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
908 if (VisitDeclaratorDecl(D))
909 return true;
910
911 if (Expr *BitWidth = D->getBitWidth())
912 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
913
914 if (Expr *Init = D->getInClassInitializer())
915 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
916
917 return false;
918 }
919
VisitVarDecl(VarDecl * D)920 bool CursorVisitor::VisitVarDecl(VarDecl *D) {
921 if (VisitDeclaratorDecl(D))
922 return true;
923
924 if (Expr *Init = D->getInit())
925 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
926
927 return false;
928 }
929
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)930 bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
931 if (VisitDeclaratorDecl(D))
932 return true;
933
934 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
935 if (Expr *DefArg = D->getDefaultArgument())
936 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
937
938 return false;
939 }
940
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)941 bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
942 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
943 // before visiting these template parameters.
944 if (VisitTemplateParameters(D->getTemplateParameters()))
945 return true;
946
947 auto *FD = D->getTemplatedDecl();
948 return VisitAttributes(FD) || VisitFunctionDecl(FD);
949 }
950
VisitClassTemplateDecl(ClassTemplateDecl * D)951 bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
952 // FIXME: Visit the "outer" template parameter lists on the TagDecl
953 // before visiting these template parameters.
954 if (VisitTemplateParameters(D->getTemplateParameters()))
955 return true;
956
957 auto *CD = D->getTemplatedDecl();
958 return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
959 }
960
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)961 bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
962 if (VisitTemplateParameters(D->getTemplateParameters()))
963 return true;
964
965 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
966 VisitTemplateArgumentLoc(D->getDefaultArgument()))
967 return true;
968
969 return false;
970 }
971
VisitObjCTypeParamDecl(ObjCTypeParamDecl * D)972 bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
973 // Visit the bound, if it's explicit.
974 if (D->hasExplicitBound()) {
975 if (auto TInfo = D->getTypeSourceInfo()) {
976 if (Visit(TInfo->getTypeLoc()))
977 return true;
978 }
979 }
980
981 return false;
982 }
983
VisitObjCMethodDecl(ObjCMethodDecl * ND)984 bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
985 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
986 if (Visit(TSInfo->getTypeLoc()))
987 return true;
988
989 for (const auto *P : ND->parameters()) {
990 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
991 return true;
992 }
993
994 return ND->isThisDeclarationADefinition() &&
995 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
996 }
997
998 template <typename DeclIt>
addRangedDeclsInContainer(DeclIt * DI_current,DeclIt DE_current,SourceManager & SM,SourceLocation EndLoc,SmallVectorImpl<Decl * > & Decls)999 static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
1000 SourceManager &SM, SourceLocation EndLoc,
1001 SmallVectorImpl<Decl *> &Decls) {
1002 DeclIt next = *DI_current;
1003 while (++next != DE_current) {
1004 Decl *D_next = *next;
1005 if (!D_next)
1006 break;
1007 SourceLocation L = D_next->getBeginLoc();
1008 if (!L.isValid())
1009 break;
1010 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
1011 *DI_current = next;
1012 Decls.push_back(D_next);
1013 continue;
1014 }
1015 break;
1016 }
1017 }
1018
VisitObjCContainerDecl(ObjCContainerDecl * D)1019 bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
1020 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
1021 // an @implementation can lexically contain Decls that are not properly
1022 // nested in the AST. When we identify such cases, we need to retrofit
1023 // this nesting here.
1024 if (!DI_current && !FileDI_current)
1025 return VisitDeclContext(D);
1026
1027 // Scan the Decls that immediately come after the container
1028 // in the current DeclContext. If any fall within the
1029 // container's lexical region, stash them into a vector
1030 // for later processing.
1031 SmallVector<Decl *, 24> DeclsInContainer;
1032 SourceLocation EndLoc = D->getSourceRange().getEnd();
1033 SourceManager &SM = AU->getSourceManager();
1034 if (EndLoc.isValid()) {
1035 if (DI_current) {
1036 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
1037 DeclsInContainer);
1038 } else {
1039 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
1040 DeclsInContainer);
1041 }
1042 }
1043
1044 // The common case.
1045 if (DeclsInContainer.empty())
1046 return VisitDeclContext(D);
1047
1048 // Get all the Decls in the DeclContext, and sort them with the
1049 // additional ones we've collected. Then visit them.
1050 for (auto *SubDecl : D->decls()) {
1051 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1052 SubDecl->getBeginLoc().isInvalid())
1053 continue;
1054 DeclsInContainer.push_back(SubDecl);
1055 }
1056
1057 // Now sort the Decls so that they appear in lexical order.
1058 llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {
1059 SourceLocation L_A = A->getBeginLoc();
1060 SourceLocation L_B = B->getBeginLoc();
1061 return L_A != L_B
1062 ? SM.isBeforeInTranslationUnit(L_A, L_B)
1063 : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());
1064 });
1065
1066 // Now visit the decls.
1067 for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),
1068 E = DeclsInContainer.end();
1069 I != E; ++I) {
1070 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
1071 const Optional<bool> &V = shouldVisitCursor(Cursor);
1072 if (!V.hasValue())
1073 continue;
1074 if (!V.getValue())
1075 return false;
1076 if (Visit(Cursor, true))
1077 return true;
1078 }
1079 return false;
1080 }
1081
VisitObjCCategoryDecl(ObjCCategoryDecl * ND)1082 bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1083 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1084 TU)))
1085 return true;
1086
1087 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1088 return true;
1089
1090 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1091 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1092 E = ND->protocol_end();
1093 I != E; ++I, ++PL)
1094 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1095 return true;
1096
1097 return VisitObjCContainerDecl(ND);
1098 }
1099
VisitObjCProtocolDecl(ObjCProtocolDecl * PID)1100 bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1101 if (!PID->isThisDeclarationADefinition())
1102 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1103
1104 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1105 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1106 E = PID->protocol_end();
1107 I != E; ++I, ++PL)
1108 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1109 return true;
1110
1111 return VisitObjCContainerDecl(PID);
1112 }
1113
VisitObjCPropertyDecl(ObjCPropertyDecl * PD)1114 bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1115 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1116 return true;
1117
1118 // FIXME: This implements a workaround with @property declarations also being
1119 // installed in the DeclContext for the @interface. Eventually this code
1120 // should be removed.
1121 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1122 if (!CDecl || !CDecl->IsClassExtension())
1123 return false;
1124
1125 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1126 if (!ID)
1127 return false;
1128
1129 IdentifierInfo *PropertyId = PD->getIdentifier();
1130 ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
1131 cast<DeclContext>(ID), PropertyId, PD->getQueryKind());
1132
1133 if (!prevDecl)
1134 return false;
1135
1136 // Visit synthesized methods since they will be skipped when visiting
1137 // the @interface.
1138 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1139 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1140 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1141 return true;
1142
1143 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1144 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1145 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1146 return true;
1147
1148 return false;
1149 }
1150
VisitObjCTypeParamList(ObjCTypeParamList * typeParamList)1151 bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1152 if (!typeParamList)
1153 return false;
1154
1155 for (auto *typeParam : *typeParamList) {
1156 // Visit the type parameter.
1157 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1158 return true;
1159 }
1160
1161 return false;
1162 }
1163
VisitObjCInterfaceDecl(ObjCInterfaceDecl * D)1164 bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1165 if (!D->isThisDeclarationADefinition()) {
1166 // Forward declaration is treated like a reference.
1167 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1168 }
1169
1170 // Objective-C type parameters.
1171 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1172 return true;
1173
1174 // Issue callbacks for super class.
1175 if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
1176 D->getSuperClass(), D->getSuperClassLoc(), TU)))
1177 return true;
1178
1179 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1180 if (Visit(SuperClassTInfo->getTypeLoc()))
1181 return true;
1182
1183 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1184 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1185 E = D->protocol_end();
1186 I != E; ++I, ++PL)
1187 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1188 return true;
1189
1190 return VisitObjCContainerDecl(D);
1191 }
1192
VisitObjCImplDecl(ObjCImplDecl * D)1193 bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1194 return VisitObjCContainerDecl(D);
1195 }
1196
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)1197 bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1198 // 'ID' could be null when dealing with invalid code.
1199 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1200 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1201 return true;
1202
1203 return VisitObjCImplDecl(D);
1204 }
1205
VisitObjCImplementationDecl(ObjCImplementationDecl * D)1206 bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1207 #if 0
1208 // Issue callbacks for super class.
1209 // FIXME: No source location information!
1210 if (D->getSuperClass() &&
1211 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1212 D->getSuperClassLoc(),
1213 TU)))
1214 return true;
1215 #endif
1216
1217 return VisitObjCImplDecl(D);
1218 }
1219
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * PD)1220 bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1221 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1222 if (PD->isIvarNameSpecified())
1223 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1224
1225 return false;
1226 }
1227
VisitNamespaceDecl(NamespaceDecl * D)1228 bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1229 return VisitDeclContext(D);
1230 }
1231
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)1232 bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1233 // Visit nested-name-specifier.
1234 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1235 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1236 return true;
1237
1238 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1239 D->getTargetNameLoc(), TU));
1240 }
1241
VisitUsingDecl(UsingDecl * D)1242 bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1243 // Visit nested-name-specifier.
1244 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1245 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1246 return true;
1247 }
1248
1249 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1250 return true;
1251
1252 return VisitDeclarationNameInfo(D->getNameInfo());
1253 }
1254
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)1255 bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1256 // Visit nested-name-specifier.
1257 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1258 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1259 return true;
1260
1261 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1262 D->getIdentLocation(), TU));
1263 }
1264
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)1265 bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1266 // Visit nested-name-specifier.
1267 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1268 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1269 return true;
1270 }
1271
1272 return VisitDeclarationNameInfo(D->getNameInfo());
1273 }
1274
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)1275 bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1276 UnresolvedUsingTypenameDecl *D) {
1277 // Visit nested-name-specifier.
1278 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1279 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1280 return true;
1281
1282 return false;
1283 }
1284
VisitStaticAssertDecl(StaticAssertDecl * D)1285 bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
1286 if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
1287 return true;
1288 if (StringLiteral *Message = D->getMessage())
1289 if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
1290 return true;
1291 return false;
1292 }
1293
VisitFriendDecl(FriendDecl * D)1294 bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {
1295 if (NamedDecl *FriendD = D->getFriendDecl()) {
1296 if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))
1297 return true;
1298 } else if (TypeSourceInfo *TI = D->getFriendType()) {
1299 if (Visit(TI->getTypeLoc()))
1300 return true;
1301 }
1302 return false;
1303 }
1304
VisitDecompositionDecl(DecompositionDecl * D)1305 bool CursorVisitor::VisitDecompositionDecl(DecompositionDecl *D) {
1306 for (auto *B : D->bindings()) {
1307 if (Visit(MakeCXCursor(B, TU, RegionOfInterest)))
1308 return true;
1309 }
1310 return VisitVarDecl(D);
1311 }
1312
VisitDeclarationNameInfo(DeclarationNameInfo Name)1313 bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1314 switch (Name.getName().getNameKind()) {
1315 case clang::DeclarationName::Identifier:
1316 case clang::DeclarationName::CXXLiteralOperatorName:
1317 case clang::DeclarationName::CXXDeductionGuideName:
1318 case clang::DeclarationName::CXXOperatorName:
1319 case clang::DeclarationName::CXXUsingDirective:
1320 return false;
1321
1322 case clang::DeclarationName::CXXConstructorName:
1323 case clang::DeclarationName::CXXDestructorName:
1324 case clang::DeclarationName::CXXConversionFunctionName:
1325 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1326 return Visit(TSInfo->getTypeLoc());
1327 return false;
1328
1329 case clang::DeclarationName::ObjCZeroArgSelector:
1330 case clang::DeclarationName::ObjCOneArgSelector:
1331 case clang::DeclarationName::ObjCMultiArgSelector:
1332 // FIXME: Per-identifier location info?
1333 return false;
1334 }
1335
1336 llvm_unreachable("Invalid DeclarationName::Kind!");
1337 }
1338
VisitNestedNameSpecifier(NestedNameSpecifier * NNS,SourceRange Range)1339 bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1340 SourceRange Range) {
1341 // FIXME: This whole routine is a hack to work around the lack of proper
1342 // source information in nested-name-specifiers (PR5791). Since we do have
1343 // a beginning source location, we can visit the first component of the
1344 // nested-name-specifier, if it's a single-token component.
1345 if (!NNS)
1346 return false;
1347
1348 // Get the first component in the nested-name-specifier.
1349 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1350 NNS = Prefix;
1351
1352 switch (NNS->getKind()) {
1353 case NestedNameSpecifier::Namespace:
1354 return Visit(
1355 MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
1356
1357 case NestedNameSpecifier::NamespaceAlias:
1358 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1359 Range.getBegin(), TU));
1360
1361 case NestedNameSpecifier::TypeSpec: {
1362 // If the type has a form where we know that the beginning of the source
1363 // range matches up with a reference cursor. Visit the appropriate reference
1364 // cursor.
1365 const Type *T = NNS->getAsType();
1366 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1367 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1368 if (const TagType *Tag = dyn_cast<TagType>(T))
1369 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1370 if (const TemplateSpecializationType *TST =
1371 dyn_cast<TemplateSpecializationType>(T))
1372 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1373 break;
1374 }
1375
1376 case NestedNameSpecifier::TypeSpecWithTemplate:
1377 case NestedNameSpecifier::Global:
1378 case NestedNameSpecifier::Identifier:
1379 case NestedNameSpecifier::Super:
1380 break;
1381 }
1382
1383 return false;
1384 }
1385
VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)1386 bool CursorVisitor::VisitNestedNameSpecifierLoc(
1387 NestedNameSpecifierLoc Qualifier) {
1388 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1389 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1390 Qualifiers.push_back(Qualifier);
1391
1392 while (!Qualifiers.empty()) {
1393 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1394 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1395 switch (NNS->getKind()) {
1396 case NestedNameSpecifier::Namespace:
1397 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1398 Q.getLocalBeginLoc(), TU)))
1399 return true;
1400
1401 break;
1402
1403 case NestedNameSpecifier::NamespaceAlias:
1404 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1405 Q.getLocalBeginLoc(), TU)))
1406 return true;
1407
1408 break;
1409
1410 case NestedNameSpecifier::TypeSpec:
1411 case NestedNameSpecifier::TypeSpecWithTemplate:
1412 if (Visit(Q.getTypeLoc()))
1413 return true;
1414
1415 break;
1416
1417 case NestedNameSpecifier::Global:
1418 case NestedNameSpecifier::Identifier:
1419 case NestedNameSpecifier::Super:
1420 break;
1421 }
1422 }
1423
1424 return false;
1425 }
1426
VisitTemplateParameters(const TemplateParameterList * Params)1427 bool CursorVisitor::VisitTemplateParameters(
1428 const TemplateParameterList *Params) {
1429 if (!Params)
1430 return false;
1431
1432 for (TemplateParameterList::const_iterator P = Params->begin(),
1433 PEnd = Params->end();
1434 P != PEnd; ++P) {
1435 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1436 return true;
1437 }
1438
1439 return false;
1440 }
1441
VisitTemplateName(TemplateName Name,SourceLocation Loc)1442 bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1443 switch (Name.getKind()) {
1444 case TemplateName::Template:
1445 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1446
1447 case TemplateName::OverloadedTemplate:
1448 // Visit the overloaded template set.
1449 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1450 return true;
1451
1452 return false;
1453
1454 case TemplateName::AssumedTemplate:
1455 // FIXME: Visit DeclarationName?
1456 return false;
1457
1458 case TemplateName::DependentTemplate:
1459 // FIXME: Visit nested-name-specifier.
1460 return false;
1461
1462 case TemplateName::QualifiedTemplate:
1463 // FIXME: Visit nested-name-specifier.
1464 return Visit(MakeCursorTemplateRef(
1465 Name.getAsQualifiedTemplateName()->getDecl(), Loc, TU));
1466
1467 case TemplateName::SubstTemplateTemplateParm:
1468 return Visit(MakeCursorTemplateRef(
1469 Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));
1470
1471 case TemplateName::SubstTemplateTemplateParmPack:
1472 return Visit(MakeCursorTemplateRef(
1473 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
1474 TU));
1475 }
1476
1477 llvm_unreachable("Invalid TemplateName::Kind!");
1478 }
1479
VisitTemplateArgumentLoc(const TemplateArgumentLoc & TAL)1480 bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1481 switch (TAL.getArgument().getKind()) {
1482 case TemplateArgument::Null:
1483 case TemplateArgument::Integral:
1484 case TemplateArgument::Pack:
1485 return false;
1486
1487 case TemplateArgument::Type:
1488 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1489 return Visit(TSInfo->getTypeLoc());
1490 return false;
1491
1492 case TemplateArgument::Declaration:
1493 if (Expr *E = TAL.getSourceDeclExpression())
1494 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1495 return false;
1496
1497 case TemplateArgument::NullPtr:
1498 if (Expr *E = TAL.getSourceNullPtrExpression())
1499 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1500 return false;
1501
1502 case TemplateArgument::Expression:
1503 if (Expr *E = TAL.getSourceExpression())
1504 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1505 return false;
1506
1507 case TemplateArgument::Template:
1508 case TemplateArgument::TemplateExpansion:
1509 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1510 return true;
1511
1512 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1513 TAL.getTemplateNameLoc());
1514 }
1515
1516 llvm_unreachable("Invalid TemplateArgument::Kind!");
1517 }
1518
VisitLinkageSpecDecl(LinkageSpecDecl * D)1519 bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1520 return VisitDeclContext(D);
1521 }
1522
VisitQualifiedTypeLoc(QualifiedTypeLoc TL)1523 bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1524 return Visit(TL.getUnqualifiedLoc());
1525 }
1526
VisitBuiltinTypeLoc(BuiltinTypeLoc TL)1527 bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1528 ASTContext &Context = AU->getASTContext();
1529
1530 // Some builtin types (such as Objective-C's "id", "sel", and
1531 // "Class") have associated declarations. Create cursors for those.
1532 QualType VisitType;
1533 switch (TL.getTypePtr()->getKind()) {
1534
1535 case BuiltinType::Void:
1536 case BuiltinType::NullPtr:
1537 case BuiltinType::Dependent:
1538 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
1539 case BuiltinType::Id:
1540 #include "clang/Basic/OpenCLImageTypes.def"
1541 #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
1542 #include "clang/Basic/OpenCLExtensionTypes.def"
1543 case BuiltinType::OCLSampler:
1544 case BuiltinType::OCLEvent:
1545 case BuiltinType::OCLClkEvent:
1546 case BuiltinType::OCLQueue:
1547 case BuiltinType::OCLReserveID:
1548 #define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1549 #include "clang/Basic/AArch64SVEACLETypes.def"
1550 #define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
1551 #include "clang/Basic/PPCTypes.def"
1552 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1553 #include "clang/Basic/RISCVVTypes.def"
1554 #define BUILTIN_TYPE(Id, SingletonId)
1555 #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1556 #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1557 #define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1558 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1559 #include "clang/AST/BuiltinTypes.def"
1560 break;
1561
1562 case BuiltinType::ObjCId:
1563 VisitType = Context.getObjCIdType();
1564 break;
1565
1566 case BuiltinType::ObjCClass:
1567 VisitType = Context.getObjCClassType();
1568 break;
1569
1570 case BuiltinType::ObjCSel:
1571 VisitType = Context.getObjCSelType();
1572 break;
1573 }
1574
1575 if (!VisitType.isNull()) {
1576 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1577 return Visit(
1578 MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
1579 }
1580
1581 return false;
1582 }
1583
VisitTypedefTypeLoc(TypedefTypeLoc TL)1584 bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1585 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1586 }
1587
VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL)1588 bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1589 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1590 }
1591
VisitTagTypeLoc(TagTypeLoc TL)1592 bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1593 if (TL.isDefinition())
1594 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1595
1596 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1597 }
1598
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)1599 bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1600 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1601 }
1602
VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL)1603 bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1604 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
1605 }
1606
VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL)1607 bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
1608 if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
1609 return true;
1610 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1611 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1612 TU)))
1613 return true;
1614 }
1615
1616 return false;
1617 }
1618
VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL)1619 bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1620 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1621 return true;
1622
1623 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1624 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1625 return true;
1626 }
1627
1628 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1629 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1630 TU)))
1631 return true;
1632 }
1633
1634 return false;
1635 }
1636
VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL)1637 bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1638 return Visit(TL.getPointeeLoc());
1639 }
1640
VisitParenTypeLoc(ParenTypeLoc TL)1641 bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1642 return Visit(TL.getInnerLoc());
1643 }
1644
VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL)1645 bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
1646 return Visit(TL.getInnerLoc());
1647 }
1648
VisitPointerTypeLoc(PointerTypeLoc TL)1649 bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1650 return Visit(TL.getPointeeLoc());
1651 }
1652
VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL)1653 bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1654 return Visit(TL.getPointeeLoc());
1655 }
1656
VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL)1657 bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1658 return Visit(TL.getPointeeLoc());
1659 }
1660
VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL)1661 bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1662 return Visit(TL.getPointeeLoc());
1663 }
1664
VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL)1665 bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1666 return Visit(TL.getPointeeLoc());
1667 }
1668
VisitAttributedTypeLoc(AttributedTypeLoc TL)1669 bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1670 return Visit(TL.getModifiedLoc());
1671 }
1672
VisitFunctionTypeLoc(FunctionTypeLoc TL,bool SkipResultType)1673 bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1674 bool SkipResultType) {
1675 if (!SkipResultType && Visit(TL.getReturnLoc()))
1676 return true;
1677
1678 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1679 if (Decl *D = TL.getParam(I))
1680 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1681 return true;
1682
1683 return false;
1684 }
1685
VisitArrayTypeLoc(ArrayTypeLoc TL)1686 bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1687 if (Visit(TL.getElementLoc()))
1688 return true;
1689
1690 if (Expr *Size = TL.getSizeExpr())
1691 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1692
1693 return false;
1694 }
1695
VisitDecayedTypeLoc(DecayedTypeLoc TL)1696 bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1697 return Visit(TL.getOriginalLoc());
1698 }
1699
VisitAdjustedTypeLoc(AdjustedTypeLoc TL)1700 bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1701 return Visit(TL.getOriginalLoc());
1702 }
1703
VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL)1704 bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
1705 DeducedTemplateSpecializationTypeLoc TL) {
1706 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1707 TL.getTemplateNameLoc()))
1708 return true;
1709
1710 return false;
1711 }
1712
VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)1713 bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1714 TemplateSpecializationTypeLoc TL) {
1715 // Visit the template name.
1716 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1717 TL.getTemplateNameLoc()))
1718 return true;
1719
1720 // Visit the template arguments.
1721 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1722 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1723 return true;
1724
1725 return false;
1726 }
1727
VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL)1728 bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1729 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1730 }
1731
VisitTypeOfTypeLoc(TypeOfTypeLoc TL)1732 bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1733 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1734 return Visit(TSInfo->getTypeLoc());
1735
1736 return false;
1737 }
1738
VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL)1739 bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1740 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1741 return Visit(TSInfo->getTypeLoc());
1742
1743 return false;
1744 }
1745
VisitDependentNameTypeLoc(DependentNameTypeLoc TL)1746 bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1747 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
1748 }
1749
VisitDependentTemplateSpecializationTypeLoc(DependentTemplateSpecializationTypeLoc TL)1750 bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1751 DependentTemplateSpecializationTypeLoc TL) {
1752 // Visit the nested-name-specifier, if there is one.
1753 if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1754 return true;
1755
1756 // Visit the template arguments.
1757 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1758 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1759 return true;
1760
1761 return false;
1762 }
1763
VisitElaboratedTypeLoc(ElaboratedTypeLoc TL)1764 bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1765 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1766 return true;
1767
1768 return Visit(TL.getNamedTypeLoc());
1769 }
1770
VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL)1771 bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1772 return Visit(TL.getPatternLoc());
1773 }
1774
VisitDecltypeTypeLoc(DecltypeTypeLoc TL)1775 bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1776 if (Expr *E = TL.getUnderlyingExpr())
1777 return Visit(MakeCXCursor(E, StmtParent, TU));
1778
1779 return false;
1780 }
1781
VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL)1782 bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1783 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1784 }
1785
VisitAtomicTypeLoc(AtomicTypeLoc TL)1786 bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1787 return Visit(TL.getValueLoc());
1788 }
1789
VisitPipeTypeLoc(PipeTypeLoc TL)1790 bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1791 return Visit(TL.getValueLoc());
1792 }
1793
1794 #define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1795 bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1796 return Visit##PARENT##Loc(TL); \
1797 }
1798
DEFAULT_TYPELOC_IMPL(Complex,Type)1799 DEFAULT_TYPELOC_IMPL(Complex, Type)
1800 DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1801 DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1802 DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1803 DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1804 DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
1805 DEFAULT_TYPELOC_IMPL(DependentVector, Type)
1806 DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1807 DEFAULT_TYPELOC_IMPL(Vector, Type)
1808 DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1809 DEFAULT_TYPELOC_IMPL(ConstantMatrix, MatrixType)
1810 DEFAULT_TYPELOC_IMPL(DependentSizedMatrix, MatrixType)
1811 DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1812 DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1813 DEFAULT_TYPELOC_IMPL(Record, TagType)
1814 DEFAULT_TYPELOC_IMPL(Enum, TagType)
1815 DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1816 DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1817 DEFAULT_TYPELOC_IMPL(Auto, Type)
1818 DEFAULT_TYPELOC_IMPL(ExtInt, Type)
1819 DEFAULT_TYPELOC_IMPL(DependentExtInt, Type)
1820
1821 bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1822 // Visit the nested-name-specifier, if present.
1823 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1824 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1825 return true;
1826
1827 if (D->isCompleteDefinition()) {
1828 for (const auto &I : D->bases()) {
1829 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
1830 return true;
1831 }
1832 }
1833
1834 return VisitTagDecl(D);
1835 }
1836
VisitAttributes(Decl * D)1837 bool CursorVisitor::VisitAttributes(Decl *D) {
1838 for (const auto *I : D->attrs())
1839 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1840 !I->isImplicit()) &&
1841 Visit(MakeCXCursor(I, D, TU)))
1842 return true;
1843
1844 return false;
1845 }
1846
1847 //===----------------------------------------------------------------------===//
1848 // Data-recursive visitor methods.
1849 //===----------------------------------------------------------------------===//
1850
1851 namespace {
1852 #define DEF_JOB(NAME, DATA, KIND) \
1853 class NAME : public VisitorJob { \
1854 public: \
1855 NAME(const DATA *d, CXCursor parent) \
1856 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1857 static bool classof(const VisitorJob *VJ) { \
1858 return VJ->getKind() == KIND; \
1859 } \
1860 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1861 };
1862
1863 DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1864 DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1865 DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1866 DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1867 DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1868 DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1869 DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1870 #undef DEF_JOB
1871
1872 class ExplicitTemplateArgsVisit : public VisitorJob {
1873 public:
ExplicitTemplateArgsVisit(const TemplateArgumentLoc * Begin,const TemplateArgumentLoc * End,CXCursor parent)1874 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1875 const TemplateArgumentLoc *End, CXCursor parent)
1876 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1877 End) {}
classof(const VisitorJob * VJ)1878 static bool classof(const VisitorJob *VJ) {
1879 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1880 }
begin() const1881 const TemplateArgumentLoc *begin() const {
1882 return static_cast<const TemplateArgumentLoc *>(data[0]);
1883 }
end()1884 const TemplateArgumentLoc *end() {
1885 return static_cast<const TemplateArgumentLoc *>(data[1]);
1886 }
1887 };
1888 class DeclVisit : public VisitorJob {
1889 public:
DeclVisit(const Decl * D,CXCursor parent,bool isFirst)1890 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1891 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1892 isFirst ? (void *)1 : (void *)nullptr) {}
classof(const VisitorJob * VJ)1893 static bool classof(const VisitorJob *VJ) {
1894 return VJ->getKind() == DeclVisitKind;
1895 }
get() const1896 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
isFirst() const1897 bool isFirst() const { return data[1] != nullptr; }
1898 };
1899 class TypeLocVisit : public VisitorJob {
1900 public:
TypeLocVisit(TypeLoc tl,CXCursor parent)1901 TypeLocVisit(TypeLoc tl, CXCursor parent)
1902 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1903 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1904
classof(const VisitorJob * VJ)1905 static bool classof(const VisitorJob *VJ) {
1906 return VJ->getKind() == TypeLocVisitKind;
1907 }
1908
get() const1909 TypeLoc get() const {
1910 QualType T = QualType::getFromOpaquePtr(data[0]);
1911 return TypeLoc(T, const_cast<void *>(data[1]));
1912 }
1913 };
1914
1915 class LabelRefVisit : public VisitorJob {
1916 public:
LabelRefVisit(LabelDecl * LD,SourceLocation labelLoc,CXCursor parent)1917 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1918 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1919 labelLoc.getPtrEncoding()) {}
1920
classof(const VisitorJob * VJ)1921 static bool classof(const VisitorJob *VJ) {
1922 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1923 }
get() const1924 const LabelDecl *get() const {
1925 return static_cast<const LabelDecl *>(data[0]);
1926 }
getLoc() const1927 SourceLocation getLoc() const {
1928 return SourceLocation::getFromPtrEncoding(data[1]);
1929 }
1930 };
1931
1932 class NestedNameSpecifierLocVisit : public VisitorJob {
1933 public:
NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier,CXCursor parent)1934 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1935 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1936 Qualifier.getNestedNameSpecifier(),
1937 Qualifier.getOpaqueData()) {}
1938
classof(const VisitorJob * VJ)1939 static bool classof(const VisitorJob *VJ) {
1940 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1941 }
1942
get() const1943 NestedNameSpecifierLoc get() const {
1944 return NestedNameSpecifierLoc(
1945 const_cast<NestedNameSpecifier *>(
1946 static_cast<const NestedNameSpecifier *>(data[0])),
1947 const_cast<void *>(data[1]));
1948 }
1949 };
1950
1951 class DeclarationNameInfoVisit : public VisitorJob {
1952 public:
DeclarationNameInfoVisit(const Stmt * S,CXCursor parent)1953 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
1954 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
classof(const VisitorJob * VJ)1955 static bool classof(const VisitorJob *VJ) {
1956 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1957 }
get() const1958 DeclarationNameInfo get() const {
1959 const Stmt *S = static_cast<const Stmt *>(data[0]);
1960 switch (S->getStmtClass()) {
1961 default:
1962 llvm_unreachable("Unhandled Stmt");
1963 case clang::Stmt::MSDependentExistsStmtClass:
1964 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1965 case Stmt::CXXDependentScopeMemberExprClass:
1966 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1967 case Stmt::DependentScopeDeclRefExprClass:
1968 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1969 case Stmt::OMPCriticalDirectiveClass:
1970 return cast<OMPCriticalDirective>(S)->getDirectiveName();
1971 }
1972 }
1973 };
1974 class MemberRefVisit : public VisitorJob {
1975 public:
MemberRefVisit(const FieldDecl * D,SourceLocation L,CXCursor parent)1976 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
1977 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1978 L.getPtrEncoding()) {}
classof(const VisitorJob * VJ)1979 static bool classof(const VisitorJob *VJ) {
1980 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1981 }
get() const1982 const FieldDecl *get() const {
1983 return static_cast<const FieldDecl *>(data[0]);
1984 }
getLoc() const1985 SourceLocation getLoc() const {
1986 return SourceLocation::getFromRawEncoding(
1987 (SourceLocation::UIntTy)(uintptr_t)data[1]);
1988 }
1989 };
1990 class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
1991 friend class OMPClauseEnqueue;
1992 VisitorWorkList &WL;
1993 CXCursor Parent;
1994
1995 public:
EnqueueVisitor(VisitorWorkList & wl,CXCursor parent)1996 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1997 : WL(wl), Parent(parent) {}
1998
1999 void VisitAddrLabelExpr(const AddrLabelExpr *E);
2000 void VisitBlockExpr(const BlockExpr *B);
2001 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
2002 void VisitCompoundStmt(const CompoundStmt *S);
VisitCXXDefaultArgExpr(const CXXDefaultArgExpr * E)2003 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
2004 }
2005 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
2006 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
2007 void VisitCXXNewExpr(const CXXNewExpr *E);
2008 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
2009 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
2010 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
2011 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
2012 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
2013 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
2014 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
2015 void VisitCXXCatchStmt(const CXXCatchStmt *S);
2016 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
2017 void VisitDeclRefExpr(const DeclRefExpr *D);
2018 void VisitDeclStmt(const DeclStmt *S);
2019 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
2020 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
2021 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
2022 void VisitForStmt(const ForStmt *FS);
2023 void VisitGotoStmt(const GotoStmt *GS);
2024 void VisitIfStmt(const IfStmt *If);
2025 void VisitInitListExpr(const InitListExpr *IE);
2026 void VisitMemberExpr(const MemberExpr *M);
2027 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2028 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2029 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2030 void VisitOverloadExpr(const OverloadExpr *E);
2031 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2032 void VisitStmt(const Stmt *S);
2033 void VisitSwitchStmt(const SwitchStmt *S);
2034 void VisitWhileStmt(const WhileStmt *W);
2035 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2036 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2037 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2038 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2039 void VisitVAArgExpr(const VAArgExpr *E);
2040 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2041 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2042 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2043 void VisitLambdaExpr(const LambdaExpr *E);
2044 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
2045 void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
2046 void VisitOMPLoopDirective(const OMPLoopDirective *D);
2047 void VisitOMPParallelDirective(const OMPParallelDirective *D);
2048 void VisitOMPSimdDirective(const OMPSimdDirective *D);
2049 void VisitOMPTileDirective(const OMPTileDirective *D);
2050 void VisitOMPUnrollDirective(const OMPUnrollDirective *D);
2051 void VisitOMPForDirective(const OMPForDirective *D);
2052 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
2053 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
2054 void VisitOMPSectionDirective(const OMPSectionDirective *D);
2055 void VisitOMPSingleDirective(const OMPSingleDirective *D);
2056 void VisitOMPMasterDirective(const OMPMasterDirective *D);
2057 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
2058 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
2059 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
2060 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
2061 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
2062 void VisitOMPTaskDirective(const OMPTaskDirective *D);
2063 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
2064 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
2065 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
2066 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
2067 void
2068 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
2069 void VisitOMPCancelDirective(const OMPCancelDirective *D);
2070 void VisitOMPFlushDirective(const OMPFlushDirective *D);
2071 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
2072 void VisitOMPScanDirective(const OMPScanDirective *D);
2073 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
2074 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
2075 void VisitOMPTargetDirective(const OMPTargetDirective *D);
2076 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
2077 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
2078 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
2079 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
2080 void
2081 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
2082 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
2083 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
2084 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
2085 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
2086 void
2087 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
2088 void VisitOMPParallelMasterTaskLoopDirective(
2089 const OMPParallelMasterTaskLoopDirective *D);
2090 void VisitOMPParallelMasterTaskLoopSimdDirective(
2091 const OMPParallelMasterTaskLoopSimdDirective *D);
2092 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
2093 void VisitOMPDistributeParallelForDirective(
2094 const OMPDistributeParallelForDirective *D);
2095 void VisitOMPDistributeParallelForSimdDirective(
2096 const OMPDistributeParallelForSimdDirective *D);
2097 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
2098 void VisitOMPTargetParallelForSimdDirective(
2099 const OMPTargetParallelForSimdDirective *D);
2100 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
2101 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
2102 void VisitOMPTeamsDistributeSimdDirective(
2103 const OMPTeamsDistributeSimdDirective *D);
2104 void VisitOMPTeamsDistributeParallelForSimdDirective(
2105 const OMPTeamsDistributeParallelForSimdDirective *D);
2106 void VisitOMPTeamsDistributeParallelForDirective(
2107 const OMPTeamsDistributeParallelForDirective *D);
2108 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
2109 void VisitOMPTargetTeamsDistributeDirective(
2110 const OMPTargetTeamsDistributeDirective *D);
2111 void VisitOMPTargetTeamsDistributeParallelForDirective(
2112 const OMPTargetTeamsDistributeParallelForDirective *D);
2113 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2114 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
2115 void VisitOMPTargetTeamsDistributeSimdDirective(
2116 const OMPTargetTeamsDistributeSimdDirective *D);
2117
2118 private:
2119 void AddDeclarationNameInfo(const Stmt *S);
2120 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
2121 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2122 unsigned NumTemplateArgs);
2123 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2124 void AddStmt(const Stmt *S);
2125 void AddDecl(const Decl *D, bool isFirst = true);
2126 void AddTypeLoc(TypeSourceInfo *TI);
2127 void EnqueueChildren(const Stmt *S);
2128 void EnqueueChildren(const OMPClause *S);
2129 };
2130 } // namespace
2131
AddDeclarationNameInfo(const Stmt * S)2132 void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
2133 // 'S' should always be non-null, since it comes from the
2134 // statement we are visiting.
2135 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2136 }
2137
AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)2138 void EnqueueVisitor::AddNestedNameSpecifierLoc(
2139 NestedNameSpecifierLoc Qualifier) {
2140 if (Qualifier)
2141 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2142 }
2143
AddStmt(const Stmt * S)2144 void EnqueueVisitor::AddStmt(const Stmt *S) {
2145 if (S)
2146 WL.push_back(StmtVisit(S, Parent));
2147 }
AddDecl(const Decl * D,bool isFirst)2148 void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
2149 if (D)
2150 WL.push_back(DeclVisit(D, Parent, isFirst));
2151 }
AddExplicitTemplateArgs(const TemplateArgumentLoc * A,unsigned NumTemplateArgs)2152 void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2153 unsigned NumTemplateArgs) {
2154 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
2155 }
AddMemberRef(const FieldDecl * D,SourceLocation L)2156 void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
2157 if (D)
2158 WL.push_back(MemberRefVisit(D, L, Parent));
2159 }
AddTypeLoc(TypeSourceInfo * TI)2160 void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2161 if (TI)
2162 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2163 }
EnqueueChildren(const Stmt * S)2164 void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
2165 unsigned size = WL.size();
2166 for (const Stmt *SubStmt : S->children()) {
2167 AddStmt(SubStmt);
2168 }
2169 if (size == WL.size())
2170 return;
2171 // Now reverse the entries we just added. This will match the DFS
2172 // ordering performed by the worklist.
2173 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2174 std::reverse(I, E);
2175 }
2176 namespace {
2177 class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2178 EnqueueVisitor *Visitor;
2179 /// Process clauses with list of variables.
2180 template <typename T> void VisitOMPClauseList(T *Node);
2181
2182 public:
OMPClauseEnqueue(EnqueueVisitor * Visitor)2183 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
2184 #define GEN_CLANG_CLAUSE_CLASS
2185 #define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2186 #include "llvm/Frontend/OpenMP/OMP.inc"
2187 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
2188 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
2189 };
2190
VisitOMPClauseWithPreInit(const OMPClauseWithPreInit * C)2191 void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2192 const OMPClauseWithPreInit *C) {
2193 Visitor->AddStmt(C->getPreInitStmt());
2194 }
2195
VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate * C)2196 void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2197 const OMPClauseWithPostUpdate *C) {
2198 VisitOMPClauseWithPreInit(C);
2199 Visitor->AddStmt(C->getPostUpdateExpr());
2200 }
2201
VisitOMPIfClause(const OMPIfClause * C)2202 void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2203 VisitOMPClauseWithPreInit(C);
2204 Visitor->AddStmt(C->getCondition());
2205 }
2206
VisitOMPFinalClause(const OMPFinalClause * C)2207 void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2208 Visitor->AddStmt(C->getCondition());
2209 }
2210
VisitOMPNumThreadsClause(const OMPNumThreadsClause * C)2211 void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2212 VisitOMPClauseWithPreInit(C);
2213 Visitor->AddStmt(C->getNumThreads());
2214 }
2215
VisitOMPSafelenClause(const OMPSafelenClause * C)2216 void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2217 Visitor->AddStmt(C->getSafelen());
2218 }
2219
VisitOMPSimdlenClause(const OMPSimdlenClause * C)2220 void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2221 Visitor->AddStmt(C->getSimdlen());
2222 }
2223
VisitOMPSizesClause(const OMPSizesClause * C)2224 void OMPClauseEnqueue::VisitOMPSizesClause(const OMPSizesClause *C) {
2225 for (auto E : C->getSizesRefs())
2226 Visitor->AddStmt(E);
2227 }
2228
VisitOMPFullClause(const OMPFullClause * C)2229 void OMPClauseEnqueue::VisitOMPFullClause(const OMPFullClause *C) {}
2230
VisitOMPPartialClause(const OMPPartialClause * C)2231 void OMPClauseEnqueue::VisitOMPPartialClause(const OMPPartialClause *C) {
2232 Visitor->AddStmt(C->getFactor());
2233 }
2234
VisitOMPAllocatorClause(const OMPAllocatorClause * C)2235 void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2236 Visitor->AddStmt(C->getAllocator());
2237 }
2238
VisitOMPCollapseClause(const OMPCollapseClause * C)2239 void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2240 Visitor->AddStmt(C->getNumForLoops());
2241 }
2242
VisitOMPDefaultClause(const OMPDefaultClause * C)2243 void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
2244
VisitOMPProcBindClause(const OMPProcBindClause * C)2245 void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
2246
VisitOMPScheduleClause(const OMPScheduleClause * C)2247 void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2248 VisitOMPClauseWithPreInit(C);
2249 Visitor->AddStmt(C->getChunkSize());
2250 }
2251
VisitOMPOrderedClause(const OMPOrderedClause * C)2252 void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2253 Visitor->AddStmt(C->getNumForLoops());
2254 }
2255
VisitOMPDetachClause(const OMPDetachClause * C)2256 void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2257 Visitor->AddStmt(C->getEventHandler());
2258 }
2259
VisitOMPNowaitClause(const OMPNowaitClause *)2260 void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2261
VisitOMPUntiedClause(const OMPUntiedClause *)2262 void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2263
VisitOMPMergeableClause(const OMPMergeableClause *)2264 void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2265
VisitOMPReadClause(const OMPReadClause *)2266 void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2267
VisitOMPWriteClause(const OMPWriteClause *)2268 void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2269
VisitOMPUpdateClause(const OMPUpdateClause *)2270 void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2271
VisitOMPCaptureClause(const OMPCaptureClause *)2272 void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2273
VisitOMPSeqCstClause(const OMPSeqCstClause *)2274 void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2275
VisitOMPAcqRelClause(const OMPAcqRelClause *)2276 void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2277
VisitOMPAcquireClause(const OMPAcquireClause *)2278 void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2279
VisitOMPReleaseClause(const OMPReleaseClause *)2280 void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2281
VisitOMPRelaxedClause(const OMPRelaxedClause *)2282 void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2283
VisitOMPThreadsClause(const OMPThreadsClause *)2284 void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2285
VisitOMPSIMDClause(const OMPSIMDClause *)2286 void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2287
VisitOMPNogroupClause(const OMPNogroupClause *)2288 void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2289
VisitOMPInitClause(const OMPInitClause * C)2290 void OMPClauseEnqueue::VisitOMPInitClause(const OMPInitClause *C) {
2291 VisitOMPClauseList(C);
2292 }
2293
VisitOMPUseClause(const OMPUseClause * C)2294 void OMPClauseEnqueue::VisitOMPUseClause(const OMPUseClause *C) {
2295 Visitor->AddStmt(C->getInteropVar());
2296 }
2297
VisitOMPDestroyClause(const OMPDestroyClause * C)2298 void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *C) {
2299 if (C->getInteropVar())
2300 Visitor->AddStmt(C->getInteropVar());
2301 }
2302
VisitOMPNovariantsClause(const OMPNovariantsClause * C)2303 void OMPClauseEnqueue::VisitOMPNovariantsClause(const OMPNovariantsClause *C) {
2304 Visitor->AddStmt(C->getCondition());
2305 }
2306
VisitOMPNocontextClause(const OMPNocontextClause * C)2307 void OMPClauseEnqueue::VisitOMPNocontextClause(const OMPNocontextClause *C) {
2308 Visitor->AddStmt(C->getCondition());
2309 }
2310
VisitOMPFilterClause(const OMPFilterClause * C)2311 void OMPClauseEnqueue::VisitOMPFilterClause(const OMPFilterClause *C) {
2312 VisitOMPClauseWithPreInit(C);
2313 Visitor->AddStmt(C->getThreadID());
2314 }
2315
VisitOMPUnifiedAddressClause(const OMPUnifiedAddressClause *)2316 void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2317 const OMPUnifiedAddressClause *) {}
2318
VisitOMPUnifiedSharedMemoryClause(const OMPUnifiedSharedMemoryClause *)2319 void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2320 const OMPUnifiedSharedMemoryClause *) {}
2321
VisitOMPReverseOffloadClause(const OMPReverseOffloadClause *)2322 void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2323 const OMPReverseOffloadClause *) {}
2324
VisitOMPDynamicAllocatorsClause(const OMPDynamicAllocatorsClause *)2325 void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2326 const OMPDynamicAllocatorsClause *) {}
2327
VisitOMPAtomicDefaultMemOrderClause(const OMPAtomicDefaultMemOrderClause *)2328 void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2329 const OMPAtomicDefaultMemOrderClause *) {}
2330
VisitOMPDeviceClause(const OMPDeviceClause * C)2331 void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2332 Visitor->AddStmt(C->getDevice());
2333 }
2334
VisitOMPNumTeamsClause(const OMPNumTeamsClause * C)2335 void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2336 VisitOMPClauseWithPreInit(C);
2337 Visitor->AddStmt(C->getNumTeams());
2338 }
2339
VisitOMPThreadLimitClause(const OMPThreadLimitClause * C)2340 void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2341 const OMPThreadLimitClause *C) {
2342 VisitOMPClauseWithPreInit(C);
2343 Visitor->AddStmt(C->getThreadLimit());
2344 }
2345
VisitOMPPriorityClause(const OMPPriorityClause * C)2346 void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2347 Visitor->AddStmt(C->getPriority());
2348 }
2349
VisitOMPGrainsizeClause(const OMPGrainsizeClause * C)2350 void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2351 Visitor->AddStmt(C->getGrainsize());
2352 }
2353
VisitOMPNumTasksClause(const OMPNumTasksClause * C)2354 void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2355 Visitor->AddStmt(C->getNumTasks());
2356 }
2357
VisitOMPHintClause(const OMPHintClause * C)2358 void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2359 Visitor->AddStmt(C->getHint());
2360 }
2361
VisitOMPClauseList(T * Node)2362 template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
2363 for (const auto *I : Node->varlists()) {
2364 Visitor->AddStmt(I);
2365 }
2366 }
2367
VisitOMPInclusiveClause(const OMPInclusiveClause * C)2368 void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2369 VisitOMPClauseList(C);
2370 }
VisitOMPExclusiveClause(const OMPExclusiveClause * C)2371 void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2372 VisitOMPClauseList(C);
2373 }
VisitOMPAllocateClause(const OMPAllocateClause * C)2374 void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2375 VisitOMPClauseList(C);
2376 Visitor->AddStmt(C->getAllocator());
2377 }
VisitOMPPrivateClause(const OMPPrivateClause * C)2378 void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
2379 VisitOMPClauseList(C);
2380 for (const auto *E : C->private_copies()) {
2381 Visitor->AddStmt(E);
2382 }
2383 }
VisitOMPFirstprivateClause(const OMPFirstprivateClause * C)2384 void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2385 const OMPFirstprivateClause *C) {
2386 VisitOMPClauseList(C);
2387 VisitOMPClauseWithPreInit(C);
2388 for (const auto *E : C->private_copies()) {
2389 Visitor->AddStmt(E);
2390 }
2391 for (const auto *E : C->inits()) {
2392 Visitor->AddStmt(E);
2393 }
2394 }
VisitOMPLastprivateClause(const OMPLastprivateClause * C)2395 void OMPClauseEnqueue::VisitOMPLastprivateClause(
2396 const OMPLastprivateClause *C) {
2397 VisitOMPClauseList(C);
2398 VisitOMPClauseWithPostUpdate(C);
2399 for (auto *E : C->private_copies()) {
2400 Visitor->AddStmt(E);
2401 }
2402 for (auto *E : C->source_exprs()) {
2403 Visitor->AddStmt(E);
2404 }
2405 for (auto *E : C->destination_exprs()) {
2406 Visitor->AddStmt(E);
2407 }
2408 for (auto *E : C->assignment_ops()) {
2409 Visitor->AddStmt(E);
2410 }
2411 }
VisitOMPSharedClause(const OMPSharedClause * C)2412 void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
2413 VisitOMPClauseList(C);
2414 }
VisitOMPReductionClause(const OMPReductionClause * C)2415 void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2416 VisitOMPClauseList(C);
2417 VisitOMPClauseWithPostUpdate(C);
2418 for (auto *E : C->privates()) {
2419 Visitor->AddStmt(E);
2420 }
2421 for (auto *E : C->lhs_exprs()) {
2422 Visitor->AddStmt(E);
2423 }
2424 for (auto *E : C->rhs_exprs()) {
2425 Visitor->AddStmt(E);
2426 }
2427 for (auto *E : C->reduction_ops()) {
2428 Visitor->AddStmt(E);
2429 }
2430 if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
2431 for (auto *E : C->copy_ops()) {
2432 Visitor->AddStmt(E);
2433 }
2434 for (auto *E : C->copy_array_temps()) {
2435 Visitor->AddStmt(E);
2436 }
2437 for (auto *E : C->copy_array_elems()) {
2438 Visitor->AddStmt(E);
2439 }
2440 }
2441 }
VisitOMPTaskReductionClause(const OMPTaskReductionClause * C)2442 void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2443 const OMPTaskReductionClause *C) {
2444 VisitOMPClauseList(C);
2445 VisitOMPClauseWithPostUpdate(C);
2446 for (auto *E : C->privates()) {
2447 Visitor->AddStmt(E);
2448 }
2449 for (auto *E : C->lhs_exprs()) {
2450 Visitor->AddStmt(E);
2451 }
2452 for (auto *E : C->rhs_exprs()) {
2453 Visitor->AddStmt(E);
2454 }
2455 for (auto *E : C->reduction_ops()) {
2456 Visitor->AddStmt(E);
2457 }
2458 }
VisitOMPInReductionClause(const OMPInReductionClause * C)2459 void OMPClauseEnqueue::VisitOMPInReductionClause(
2460 const OMPInReductionClause *C) {
2461 VisitOMPClauseList(C);
2462 VisitOMPClauseWithPostUpdate(C);
2463 for (auto *E : C->privates()) {
2464 Visitor->AddStmt(E);
2465 }
2466 for (auto *E : C->lhs_exprs()) {
2467 Visitor->AddStmt(E);
2468 }
2469 for (auto *E : C->rhs_exprs()) {
2470 Visitor->AddStmt(E);
2471 }
2472 for (auto *E : C->reduction_ops()) {
2473 Visitor->AddStmt(E);
2474 }
2475 for (auto *E : C->taskgroup_descriptors())
2476 Visitor->AddStmt(E);
2477 }
VisitOMPLinearClause(const OMPLinearClause * C)2478 void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2479 VisitOMPClauseList(C);
2480 VisitOMPClauseWithPostUpdate(C);
2481 for (const auto *E : C->privates()) {
2482 Visitor->AddStmt(E);
2483 }
2484 for (const auto *E : C->inits()) {
2485 Visitor->AddStmt(E);
2486 }
2487 for (const auto *E : C->updates()) {
2488 Visitor->AddStmt(E);
2489 }
2490 for (const auto *E : C->finals()) {
2491 Visitor->AddStmt(E);
2492 }
2493 Visitor->AddStmt(C->getStep());
2494 Visitor->AddStmt(C->getCalcStep());
2495 }
VisitOMPAlignedClause(const OMPAlignedClause * C)2496 void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2497 VisitOMPClauseList(C);
2498 Visitor->AddStmt(C->getAlignment());
2499 }
VisitOMPCopyinClause(const OMPCopyinClause * C)2500 void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2501 VisitOMPClauseList(C);
2502 for (auto *E : C->source_exprs()) {
2503 Visitor->AddStmt(E);
2504 }
2505 for (auto *E : C->destination_exprs()) {
2506 Visitor->AddStmt(E);
2507 }
2508 for (auto *E : C->assignment_ops()) {
2509 Visitor->AddStmt(E);
2510 }
2511 }
VisitOMPCopyprivateClause(const OMPCopyprivateClause * C)2512 void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2513 const OMPCopyprivateClause *C) {
2514 VisitOMPClauseList(C);
2515 for (auto *E : C->source_exprs()) {
2516 Visitor->AddStmt(E);
2517 }
2518 for (auto *E : C->destination_exprs()) {
2519 Visitor->AddStmt(E);
2520 }
2521 for (auto *E : C->assignment_ops()) {
2522 Visitor->AddStmt(E);
2523 }
2524 }
VisitOMPFlushClause(const OMPFlushClause * C)2525 void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2526 VisitOMPClauseList(C);
2527 }
VisitOMPDepobjClause(const OMPDepobjClause * C)2528 void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2529 Visitor->AddStmt(C->getDepobj());
2530 }
VisitOMPDependClause(const OMPDependClause * C)2531 void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2532 VisitOMPClauseList(C);
2533 }
VisitOMPMapClause(const OMPMapClause * C)2534 void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2535 VisitOMPClauseList(C);
2536 }
VisitOMPDistScheduleClause(const OMPDistScheduleClause * C)2537 void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2538 const OMPDistScheduleClause *C) {
2539 VisitOMPClauseWithPreInit(C);
2540 Visitor->AddStmt(C->getChunkSize());
2541 }
VisitOMPDefaultmapClause(const OMPDefaultmapClause *)2542 void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2543 const OMPDefaultmapClause * /*C*/) {}
VisitOMPToClause(const OMPToClause * C)2544 void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2545 VisitOMPClauseList(C);
2546 }
VisitOMPFromClause(const OMPFromClause * C)2547 void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2548 VisitOMPClauseList(C);
2549 }
VisitOMPUseDevicePtrClause(const OMPUseDevicePtrClause * C)2550 void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2551 const OMPUseDevicePtrClause *C) {
2552 VisitOMPClauseList(C);
2553 }
VisitOMPUseDeviceAddrClause(const OMPUseDeviceAddrClause * C)2554 void OMPClauseEnqueue::VisitOMPUseDeviceAddrClause(
2555 const OMPUseDeviceAddrClause *C) {
2556 VisitOMPClauseList(C);
2557 }
VisitOMPIsDevicePtrClause(const OMPIsDevicePtrClause * C)2558 void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2559 const OMPIsDevicePtrClause *C) {
2560 VisitOMPClauseList(C);
2561 }
VisitOMPNontemporalClause(const OMPNontemporalClause * C)2562 void OMPClauseEnqueue::VisitOMPNontemporalClause(
2563 const OMPNontemporalClause *C) {
2564 VisitOMPClauseList(C);
2565 for (const auto *E : C->private_refs())
2566 Visitor->AddStmt(E);
2567 }
VisitOMPOrderClause(const OMPOrderClause * C)2568 void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
VisitOMPUsesAllocatorsClause(const OMPUsesAllocatorsClause * C)2569 void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
2570 const OMPUsesAllocatorsClause *C) {
2571 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
2572 const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);
2573 Visitor->AddStmt(D.Allocator);
2574 Visitor->AddStmt(D.AllocatorTraits);
2575 }
2576 }
VisitOMPAffinityClause(const OMPAffinityClause * C)2577 void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) {
2578 Visitor->AddStmt(C->getModifier());
2579 for (const Expr *E : C->varlists())
2580 Visitor->AddStmt(E);
2581 }
2582 } // namespace
2583
EnqueueChildren(const OMPClause * S)2584 void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2585 unsigned size = WL.size();
2586 OMPClauseEnqueue Visitor(this);
2587 Visitor.Visit(S);
2588 if (size == WL.size())
2589 return;
2590 // Now reverse the entries we just added. This will match the DFS
2591 // ordering performed by the worklist.
2592 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2593 std::reverse(I, E);
2594 }
VisitAddrLabelExpr(const AddrLabelExpr * E)2595 void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
2596 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2597 }
VisitBlockExpr(const BlockExpr * B)2598 void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
2599 AddDecl(B->getBlockDecl());
2600 }
VisitCompoundLiteralExpr(const CompoundLiteralExpr * E)2601 void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
2602 EnqueueChildren(E);
2603 AddTypeLoc(E->getTypeSourceInfo());
2604 }
VisitCompoundStmt(const CompoundStmt * S)2605 void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2606 for (auto &I : llvm::reverse(S->body()))
2607 AddStmt(I);
2608 }
VisitMSDependentExistsStmt(const MSDependentExistsStmt * S)2609 void EnqueueVisitor::VisitMSDependentExistsStmt(
2610 const MSDependentExistsStmt *S) {
2611 AddStmt(S->getSubStmt());
2612 AddDeclarationNameInfo(S);
2613 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2614 AddNestedNameSpecifierLoc(QualifierLoc);
2615 }
2616
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr * E)2617 void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2618 const CXXDependentScopeMemberExpr *E) {
2619 if (E->hasExplicitTemplateArgs())
2620 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2621 AddDeclarationNameInfo(E);
2622 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2623 AddNestedNameSpecifierLoc(QualifierLoc);
2624 if (!E->isImplicitAccess())
2625 AddStmt(E->getBase());
2626 }
VisitCXXNewExpr(const CXXNewExpr * E)2627 void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
2628 // Enqueue the initializer , if any.
2629 AddStmt(E->getInitializer());
2630 // Enqueue the array size, if any.
2631 AddStmt(E->getArraySize().getValueOr(nullptr));
2632 // Enqueue the allocated type.
2633 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2634 // Enqueue the placement arguments.
2635 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2636 AddStmt(E->getPlacementArg(I - 1));
2637 }
VisitCXXOperatorCallExpr(const CXXOperatorCallExpr * CE)2638 void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
2639 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2640 AddStmt(CE->getArg(I - 1));
2641 AddStmt(CE->getCallee());
2642 AddStmt(CE->getArg(0));
2643 }
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)2644 void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2645 const CXXPseudoDestructorExpr *E) {
2646 // Visit the name of the type being destroyed.
2647 AddTypeLoc(E->getDestroyedTypeInfo());
2648 // Visit the scope type that looks disturbingly like the nested-name-specifier
2649 // but isn't.
2650 AddTypeLoc(E->getScopeTypeInfo());
2651 // Visit the nested-name-specifier.
2652 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2653 AddNestedNameSpecifierLoc(QualifierLoc);
2654 // Visit base expression.
2655 AddStmt(E->getBase());
2656 }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)2657 void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2658 const CXXScalarValueInitExpr *E) {
2659 AddTypeLoc(E->getTypeSourceInfo());
2660 }
VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr * E)2661 void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2662 const CXXTemporaryObjectExpr *E) {
2663 EnqueueChildren(E);
2664 AddTypeLoc(E->getTypeSourceInfo());
2665 }
VisitCXXTypeidExpr(const CXXTypeidExpr * E)2666 void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
2667 EnqueueChildren(E);
2668 if (E->isTypeOperand())
2669 AddTypeLoc(E->getTypeOperandSourceInfo());
2670 }
2671
VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr * E)2672 void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2673 const CXXUnresolvedConstructExpr *E) {
2674 EnqueueChildren(E);
2675 AddTypeLoc(E->getTypeSourceInfo());
2676 }
VisitCXXUuidofExpr(const CXXUuidofExpr * E)2677 void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
2678 EnqueueChildren(E);
2679 if (E->isTypeOperand())
2680 AddTypeLoc(E->getTypeOperandSourceInfo());
2681 }
2682
VisitCXXCatchStmt(const CXXCatchStmt * S)2683 void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
2684 EnqueueChildren(S);
2685 AddDecl(S->getExceptionDecl());
2686 }
2687
VisitCXXForRangeStmt(const CXXForRangeStmt * S)2688 void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
2689 AddStmt(S->getBody());
2690 AddStmt(S->getRangeInit());
2691 AddDecl(S->getLoopVariable());
2692 }
2693
VisitDeclRefExpr(const DeclRefExpr * DR)2694 void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
2695 if (DR->hasExplicitTemplateArgs())
2696 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
2697 WL.push_back(DeclRefExprParts(DR, Parent));
2698 }
VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr * E)2699 void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2700 const DependentScopeDeclRefExpr *E) {
2701 if (E->hasExplicitTemplateArgs())
2702 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2703 AddDeclarationNameInfo(E);
2704 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2705 }
VisitDeclStmt(const DeclStmt * S)2706 void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
2707 unsigned size = WL.size();
2708 bool isFirst = true;
2709 for (const auto *D : S->decls()) {
2710 AddDecl(D, isFirst);
2711 isFirst = false;
2712 }
2713 if (size == WL.size())
2714 return;
2715 // Now reverse the entries we just added. This will match the DFS
2716 // ordering performed by the worklist.
2717 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2718 std::reverse(I, E);
2719 }
VisitDesignatedInitExpr(const DesignatedInitExpr * E)2720 void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
2721 AddStmt(E->getInit());
2722 for (const DesignatedInitExpr::Designator &D :
2723 llvm::reverse(E->designators())) {
2724 if (D.isFieldDesignator()) {
2725 if (FieldDecl *Field = D.getField())
2726 AddMemberRef(Field, D.getFieldLoc());
2727 continue;
2728 }
2729 if (D.isArrayDesignator()) {
2730 AddStmt(E->getArrayIndex(D));
2731 continue;
2732 }
2733 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2734 AddStmt(E->getArrayRangeEnd(D));
2735 AddStmt(E->getArrayRangeStart(D));
2736 }
2737 }
VisitExplicitCastExpr(const ExplicitCastExpr * E)2738 void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
2739 EnqueueChildren(E);
2740 AddTypeLoc(E->getTypeInfoAsWritten());
2741 }
VisitForStmt(const ForStmt * FS)2742 void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
2743 AddStmt(FS->getBody());
2744 AddStmt(FS->getInc());
2745 AddStmt(FS->getCond());
2746 AddDecl(FS->getConditionVariable());
2747 AddStmt(FS->getInit());
2748 }
VisitGotoStmt(const GotoStmt * GS)2749 void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
2750 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2751 }
VisitIfStmt(const IfStmt * If)2752 void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
2753 AddStmt(If->getElse());
2754 AddStmt(If->getThen());
2755 AddStmt(If->getCond());
2756 AddStmt(If->getInit());
2757 AddDecl(If->getConditionVariable());
2758 }
VisitInitListExpr(const InitListExpr * IE)2759 void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
2760 // We care about the syntactic form of the initializer list, only.
2761 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2762 IE = Syntactic;
2763 EnqueueChildren(IE);
2764 }
VisitMemberExpr(const MemberExpr * M)2765 void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
2766 WL.push_back(MemberExprParts(M, Parent));
2767
2768 // If the base of the member access expression is an implicit 'this', don't
2769 // visit it.
2770 // FIXME: If we ever want to show these implicit accesses, this will be
2771 // unfortunate. However, clang_getCursor() relies on this behavior.
2772 if (M->isImplicitAccess())
2773 return;
2774
2775 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2776 // real field that we are interested in.
2777 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2778 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2779 if (FD->isAnonymousStructOrUnion()) {
2780 AddStmt(SubME->getBase());
2781 return;
2782 }
2783 }
2784 }
2785
2786 AddStmt(M->getBase());
2787 }
VisitObjCEncodeExpr(const ObjCEncodeExpr * E)2788 void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
2789 AddTypeLoc(E->getEncodedTypeSourceInfo());
2790 }
VisitObjCMessageExpr(const ObjCMessageExpr * M)2791 void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
2792 EnqueueChildren(M);
2793 AddTypeLoc(M->getClassReceiverTypeInfo());
2794 }
VisitOffsetOfExpr(const OffsetOfExpr * E)2795 void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
2796 // Visit the components of the offsetof expression.
2797 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2798 const OffsetOfNode &Node = E->getComponent(I - 1);
2799 switch (Node.getKind()) {
2800 case OffsetOfNode::Array:
2801 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2802 break;
2803 case OffsetOfNode::Field:
2804 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2805 break;
2806 case OffsetOfNode::Identifier:
2807 case OffsetOfNode::Base:
2808 continue;
2809 }
2810 }
2811 // Visit the type into which we're computing the offset.
2812 AddTypeLoc(E->getTypeSourceInfo());
2813 }
VisitOverloadExpr(const OverloadExpr * E)2814 void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
2815 if (E->hasExplicitTemplateArgs())
2816 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2817 WL.push_back(OverloadExprParts(E, Parent));
2818 }
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)2819 void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2820 const UnaryExprOrTypeTraitExpr *E) {
2821 EnqueueChildren(E);
2822 if (E->isArgumentType())
2823 AddTypeLoc(E->getArgumentTypeInfo());
2824 }
VisitStmt(const Stmt * S)2825 void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
VisitSwitchStmt(const SwitchStmt * S)2826 void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
2827 AddStmt(S->getBody());
2828 AddStmt(S->getCond());
2829 AddDecl(S->getConditionVariable());
2830 }
2831
VisitWhileStmt(const WhileStmt * W)2832 void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
2833 AddStmt(W->getBody());
2834 AddStmt(W->getCond());
2835 AddDecl(W->getConditionVariable());
2836 }
2837
VisitTypeTraitExpr(const TypeTraitExpr * E)2838 void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
2839 for (unsigned I = E->getNumArgs(); I > 0; --I)
2840 AddTypeLoc(E->getArg(I - 1));
2841 }
2842
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)2843 void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
2844 AddTypeLoc(E->getQueriedTypeSourceInfo());
2845 }
2846
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)2847 void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
2848 EnqueueChildren(E);
2849 }
2850
VisitUnresolvedMemberExpr(const UnresolvedMemberExpr * U)2851 void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
2852 VisitOverloadExpr(U);
2853 if (!U->isImplicitAccess())
2854 AddStmt(U->getBase());
2855 }
VisitVAArgExpr(const VAArgExpr * E)2856 void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
2857 AddStmt(E->getSubExpr());
2858 AddTypeLoc(E->getWrittenTypeInfo());
2859 }
VisitSizeOfPackExpr(const SizeOfPackExpr * E)2860 void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
2861 WL.push_back(SizeOfPackExprParts(E, Parent));
2862 }
VisitOpaqueValueExpr(const OpaqueValueExpr * E)2863 void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2864 // If the opaque value has a source expression, just transparently
2865 // visit that. This is useful for (e.g.) pseudo-object expressions.
2866 if (Expr *SourceExpr = E->getSourceExpr())
2867 return Visit(SourceExpr);
2868 }
VisitLambdaExpr(const LambdaExpr * E)2869 void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
2870 AddStmt(E->getBody());
2871 WL.push_back(LambdaExprParts(E, Parent));
2872 }
VisitPseudoObjectExpr(const PseudoObjectExpr * E)2873 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
2874 // Treat the expression like its syntactic form.
2875 Visit(E->getSyntacticForm());
2876 }
2877
VisitOMPExecutableDirective(const OMPExecutableDirective * D)2878 void EnqueueVisitor::VisitOMPExecutableDirective(
2879 const OMPExecutableDirective *D) {
2880 EnqueueChildren(D);
2881 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2882 E = D->clauses().end();
2883 I != E; ++I)
2884 EnqueueChildren(*I);
2885 }
2886
VisitOMPLoopBasedDirective(const OMPLoopBasedDirective * D)2887 void EnqueueVisitor::VisitOMPLoopBasedDirective(
2888 const OMPLoopBasedDirective *D) {
2889 VisitOMPExecutableDirective(D);
2890 }
2891
VisitOMPLoopDirective(const OMPLoopDirective * D)2892 void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2893 VisitOMPLoopBasedDirective(D);
2894 }
2895
VisitOMPParallelDirective(const OMPParallelDirective * D)2896 void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2897 VisitOMPExecutableDirective(D);
2898 }
2899
VisitOMPSimdDirective(const OMPSimdDirective * D)2900 void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2901 VisitOMPLoopDirective(D);
2902 }
2903
VisitOMPTileDirective(const OMPTileDirective * D)2904 void EnqueueVisitor::VisitOMPTileDirective(const OMPTileDirective *D) {
2905 VisitOMPLoopBasedDirective(D);
2906 }
2907
VisitOMPUnrollDirective(const OMPUnrollDirective * D)2908 void EnqueueVisitor::VisitOMPUnrollDirective(const OMPUnrollDirective *D) {
2909 VisitOMPLoopBasedDirective(D);
2910 }
2911
VisitOMPForDirective(const OMPForDirective * D)2912 void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2913 VisitOMPLoopDirective(D);
2914 }
2915
VisitOMPForSimdDirective(const OMPForSimdDirective * D)2916 void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2917 VisitOMPLoopDirective(D);
2918 }
2919
VisitOMPSectionsDirective(const OMPSectionsDirective * D)2920 void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2921 VisitOMPExecutableDirective(D);
2922 }
2923
VisitOMPSectionDirective(const OMPSectionDirective * D)2924 void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2925 VisitOMPExecutableDirective(D);
2926 }
2927
VisitOMPSingleDirective(const OMPSingleDirective * D)2928 void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2929 VisitOMPExecutableDirective(D);
2930 }
2931
VisitOMPMasterDirective(const OMPMasterDirective * D)2932 void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2933 VisitOMPExecutableDirective(D);
2934 }
2935
VisitOMPCriticalDirective(const OMPCriticalDirective * D)2936 void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2937 VisitOMPExecutableDirective(D);
2938 AddDeclarationNameInfo(D);
2939 }
2940
VisitOMPParallelForDirective(const OMPParallelForDirective * D)2941 void EnqueueVisitor::VisitOMPParallelForDirective(
2942 const OMPParallelForDirective *D) {
2943 VisitOMPLoopDirective(D);
2944 }
2945
VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective * D)2946 void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2947 const OMPParallelForSimdDirective *D) {
2948 VisitOMPLoopDirective(D);
2949 }
2950
VisitOMPParallelMasterDirective(const OMPParallelMasterDirective * D)2951 void EnqueueVisitor::VisitOMPParallelMasterDirective(
2952 const OMPParallelMasterDirective *D) {
2953 VisitOMPExecutableDirective(D);
2954 }
2955
VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective * D)2956 void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2957 const OMPParallelSectionsDirective *D) {
2958 VisitOMPExecutableDirective(D);
2959 }
2960
VisitOMPTaskDirective(const OMPTaskDirective * D)2961 void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2962 VisitOMPExecutableDirective(D);
2963 }
2964
VisitOMPTaskyieldDirective(const OMPTaskyieldDirective * D)2965 void EnqueueVisitor::VisitOMPTaskyieldDirective(
2966 const OMPTaskyieldDirective *D) {
2967 VisitOMPExecutableDirective(D);
2968 }
2969
VisitOMPBarrierDirective(const OMPBarrierDirective * D)2970 void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2971 VisitOMPExecutableDirective(D);
2972 }
2973
VisitOMPTaskwaitDirective(const OMPTaskwaitDirective * D)2974 void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2975 VisitOMPExecutableDirective(D);
2976 }
2977
VisitOMPTaskgroupDirective(const OMPTaskgroupDirective * D)2978 void EnqueueVisitor::VisitOMPTaskgroupDirective(
2979 const OMPTaskgroupDirective *D) {
2980 VisitOMPExecutableDirective(D);
2981 if (const Expr *E = D->getReductionRef())
2982 VisitStmt(E);
2983 }
2984
VisitOMPFlushDirective(const OMPFlushDirective * D)2985 void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2986 VisitOMPExecutableDirective(D);
2987 }
2988
VisitOMPDepobjDirective(const OMPDepobjDirective * D)2989 void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
2990 VisitOMPExecutableDirective(D);
2991 }
2992
VisitOMPScanDirective(const OMPScanDirective * D)2993 void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
2994 VisitOMPExecutableDirective(D);
2995 }
2996
VisitOMPOrderedDirective(const OMPOrderedDirective * D)2997 void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2998 VisitOMPExecutableDirective(D);
2999 }
3000
VisitOMPAtomicDirective(const OMPAtomicDirective * D)3001 void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
3002 VisitOMPExecutableDirective(D);
3003 }
3004
VisitOMPTargetDirective(const OMPTargetDirective * D)3005 void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
3006 VisitOMPExecutableDirective(D);
3007 }
3008
VisitOMPTargetDataDirective(const OMPTargetDataDirective * D)3009 void EnqueueVisitor::VisitOMPTargetDataDirective(
3010 const OMPTargetDataDirective *D) {
3011 VisitOMPExecutableDirective(D);
3012 }
3013
VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective * D)3014 void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
3015 const OMPTargetEnterDataDirective *D) {
3016 VisitOMPExecutableDirective(D);
3017 }
3018
VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective * D)3019 void EnqueueVisitor::VisitOMPTargetExitDataDirective(
3020 const OMPTargetExitDataDirective *D) {
3021 VisitOMPExecutableDirective(D);
3022 }
3023
VisitOMPTargetParallelDirective(const OMPTargetParallelDirective * D)3024 void EnqueueVisitor::VisitOMPTargetParallelDirective(
3025 const OMPTargetParallelDirective *D) {
3026 VisitOMPExecutableDirective(D);
3027 }
3028
VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective * D)3029 void EnqueueVisitor::VisitOMPTargetParallelForDirective(
3030 const OMPTargetParallelForDirective *D) {
3031 VisitOMPLoopDirective(D);
3032 }
3033
VisitOMPTeamsDirective(const OMPTeamsDirective * D)3034 void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
3035 VisitOMPExecutableDirective(D);
3036 }
3037
VisitOMPCancellationPointDirective(const OMPCancellationPointDirective * D)3038 void EnqueueVisitor::VisitOMPCancellationPointDirective(
3039 const OMPCancellationPointDirective *D) {
3040 VisitOMPExecutableDirective(D);
3041 }
3042
VisitOMPCancelDirective(const OMPCancelDirective * D)3043 void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
3044 VisitOMPExecutableDirective(D);
3045 }
3046
VisitOMPTaskLoopDirective(const OMPTaskLoopDirective * D)3047 void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
3048 VisitOMPLoopDirective(D);
3049 }
3050
VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective * D)3051 void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
3052 const OMPTaskLoopSimdDirective *D) {
3053 VisitOMPLoopDirective(D);
3054 }
3055
VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective * D)3056 void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
3057 const OMPMasterTaskLoopDirective *D) {
3058 VisitOMPLoopDirective(D);
3059 }
3060
VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective * D)3061 void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
3062 const OMPMasterTaskLoopSimdDirective *D) {
3063 VisitOMPLoopDirective(D);
3064 }
3065
VisitOMPParallelMasterTaskLoopDirective(const OMPParallelMasterTaskLoopDirective * D)3066 void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
3067 const OMPParallelMasterTaskLoopDirective *D) {
3068 VisitOMPLoopDirective(D);
3069 }
3070
VisitOMPParallelMasterTaskLoopSimdDirective(const OMPParallelMasterTaskLoopSimdDirective * D)3071 void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
3072 const OMPParallelMasterTaskLoopSimdDirective *D) {
3073 VisitOMPLoopDirective(D);
3074 }
3075
VisitOMPDistributeDirective(const OMPDistributeDirective * D)3076 void EnqueueVisitor::VisitOMPDistributeDirective(
3077 const OMPDistributeDirective *D) {
3078 VisitOMPLoopDirective(D);
3079 }
3080
VisitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective * D)3081 void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
3082 const OMPDistributeParallelForDirective *D) {
3083 VisitOMPLoopDirective(D);
3084 }
3085
VisitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective * D)3086 void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
3087 const OMPDistributeParallelForSimdDirective *D) {
3088 VisitOMPLoopDirective(D);
3089 }
3090
VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective * D)3091 void EnqueueVisitor::VisitOMPDistributeSimdDirective(
3092 const OMPDistributeSimdDirective *D) {
3093 VisitOMPLoopDirective(D);
3094 }
3095
VisitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective * D)3096 void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
3097 const OMPTargetParallelForSimdDirective *D) {
3098 VisitOMPLoopDirective(D);
3099 }
3100
VisitOMPTargetSimdDirective(const OMPTargetSimdDirective * D)3101 void EnqueueVisitor::VisitOMPTargetSimdDirective(
3102 const OMPTargetSimdDirective *D) {
3103 VisitOMPLoopDirective(D);
3104 }
3105
VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective * D)3106 void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3107 const OMPTeamsDistributeDirective *D) {
3108 VisitOMPLoopDirective(D);
3109 }
3110
VisitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective * D)3111 void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3112 const OMPTeamsDistributeSimdDirective *D) {
3113 VisitOMPLoopDirective(D);
3114 }
3115
VisitOMPTeamsDistributeParallelForSimdDirective(const OMPTeamsDistributeParallelForSimdDirective * D)3116 void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3117 const OMPTeamsDistributeParallelForSimdDirective *D) {
3118 VisitOMPLoopDirective(D);
3119 }
3120
VisitOMPTeamsDistributeParallelForDirective(const OMPTeamsDistributeParallelForDirective * D)3121 void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3122 const OMPTeamsDistributeParallelForDirective *D) {
3123 VisitOMPLoopDirective(D);
3124 }
3125
VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective * D)3126 void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3127 const OMPTargetTeamsDirective *D) {
3128 VisitOMPExecutableDirective(D);
3129 }
3130
VisitOMPTargetTeamsDistributeDirective(const OMPTargetTeamsDistributeDirective * D)3131 void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3132 const OMPTargetTeamsDistributeDirective *D) {
3133 VisitOMPLoopDirective(D);
3134 }
3135
VisitOMPTargetTeamsDistributeParallelForDirective(const OMPTargetTeamsDistributeParallelForDirective * D)3136 void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3137 const OMPTargetTeamsDistributeParallelForDirective *D) {
3138 VisitOMPLoopDirective(D);
3139 }
3140
VisitOMPTargetTeamsDistributeParallelForSimdDirective(const OMPTargetTeamsDistributeParallelForSimdDirective * D)3141 void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3142 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3143 VisitOMPLoopDirective(D);
3144 }
3145
VisitOMPTargetTeamsDistributeSimdDirective(const OMPTargetTeamsDistributeSimdDirective * D)3146 void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3147 const OMPTargetTeamsDistributeSimdDirective *D) {
3148 VisitOMPLoopDirective(D);
3149 }
3150
EnqueueWorkList(VisitorWorkList & WL,const Stmt * S)3151 void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
3152 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3153 .Visit(S);
3154 }
3155
IsInRegionOfInterest(CXCursor C)3156 bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3157 if (RegionOfInterest.isValid()) {
3158 SourceRange Range = getRawCursorExtent(C);
3159 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3160 return false;
3161 }
3162 return true;
3163 }
3164
RunVisitorWorkList(VisitorWorkList & WL)3165 bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3166 while (!WL.empty()) {
3167 // Dequeue the worklist item.
3168 VisitorJob LI = WL.pop_back_val();
3169
3170 // Set the Parent field, then back to its old value once we're done.
3171 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
3172
3173 switch (LI.getKind()) {
3174 case VisitorJob::DeclVisitKind: {
3175 const Decl *D = cast<DeclVisit>(&LI)->get();
3176 if (!D)
3177 continue;
3178
3179 // For now, perform default visitation for Decls.
3180 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3181 cast<DeclVisit>(&LI)->isFirst())))
3182 return true;
3183
3184 continue;
3185 }
3186 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3187 for (const TemplateArgumentLoc &Arg :
3188 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3189 if (VisitTemplateArgumentLoc(Arg))
3190 return true;
3191 }
3192 continue;
3193 }
3194 case VisitorJob::TypeLocVisitKind: {
3195 // Perform default visitation for TypeLocs.
3196 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3197 return true;
3198 continue;
3199 }
3200 case VisitorJob::LabelRefVisitKind: {
3201 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3202 if (LabelStmt *stmt = LS->getStmt()) {
3203 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3204 TU))) {
3205 return true;
3206 }
3207 }
3208 continue;
3209 }
3210
3211 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3212 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3213 if (VisitNestedNameSpecifierLoc(V->get()))
3214 return true;
3215 continue;
3216 }
3217
3218 case VisitorJob::DeclarationNameInfoVisitKind: {
3219 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3220 return true;
3221 continue;
3222 }
3223 case VisitorJob::MemberRefVisitKind: {
3224 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3225 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3226 return true;
3227 continue;
3228 }
3229 case VisitorJob::StmtVisitKind: {
3230 const Stmt *S = cast<StmtVisit>(&LI)->get();
3231 if (!S)
3232 continue;
3233
3234 // Update the current cursor.
3235 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3236 if (!IsInRegionOfInterest(Cursor))
3237 continue;
3238 switch (Visitor(Cursor, Parent, ClientData)) {
3239 case CXChildVisit_Break:
3240 return true;
3241 case CXChildVisit_Continue:
3242 break;
3243 case CXChildVisit_Recurse:
3244 if (PostChildrenVisitor)
3245 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3246 EnqueueWorkList(WL, S);
3247 break;
3248 }
3249 continue;
3250 }
3251 case VisitorJob::MemberExprPartsKind: {
3252 // Handle the other pieces in the MemberExpr besides the base.
3253 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
3254
3255 // Visit the nested-name-specifier
3256 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3257 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3258 return true;
3259
3260 // Visit the declaration name.
3261 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3262 return true;
3263
3264 // Visit the explicitly-specified template arguments, if any.
3265 if (M->hasExplicitTemplateArgs()) {
3266 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3267 *ArgEnd = Arg + M->getNumTemplateArgs();
3268 Arg != ArgEnd; ++Arg) {
3269 if (VisitTemplateArgumentLoc(*Arg))
3270 return true;
3271 }
3272 }
3273 continue;
3274 }
3275 case VisitorJob::DeclRefExprPartsKind: {
3276 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3277 // Visit nested-name-specifier, if present.
3278 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3279 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3280 return true;
3281 // Visit declaration name.
3282 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3283 return true;
3284 continue;
3285 }
3286 case VisitorJob::OverloadExprPartsKind: {
3287 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3288 // Visit the nested-name-specifier.
3289 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3290 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3291 return true;
3292 // Visit the declaration name.
3293 if (VisitDeclarationNameInfo(O->getNameInfo()))
3294 return true;
3295 // Visit the overloaded declaration reference.
3296 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3297 return true;
3298 continue;
3299 }
3300 case VisitorJob::SizeOfPackExprPartsKind: {
3301 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3302 NamedDecl *Pack = E->getPack();
3303 if (isa<TemplateTypeParmDecl>(Pack)) {
3304 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3305 E->getPackLoc(), TU)))
3306 return true;
3307
3308 continue;
3309 }
3310
3311 if (isa<TemplateTemplateParmDecl>(Pack)) {
3312 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3313 E->getPackLoc(), TU)))
3314 return true;
3315
3316 continue;
3317 }
3318
3319 // Non-type template parameter packs and function parameter packs are
3320 // treated like DeclRefExpr cursors.
3321 continue;
3322 }
3323
3324 case VisitorJob::LambdaExprPartsKind: {
3325 // Visit non-init captures.
3326 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3327 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3328 CEnd = E->explicit_capture_end();
3329 C != CEnd; ++C) {
3330 if (!C->capturesVariable())
3331 continue;
3332
3333 if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
3334 TU)))
3335 return true;
3336 }
3337 // Visit init captures
3338 for (auto InitExpr : E->capture_inits()) {
3339 if (InitExpr && Visit(InitExpr))
3340 return true;
3341 }
3342
3343 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3344 // Visit parameters and return type, if present.
3345 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3346 if (E->hasExplicitParameters()) {
3347 // Visit parameters.
3348 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3349 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3350 return true;
3351 }
3352 if (E->hasExplicitResultType()) {
3353 // Visit result type.
3354 if (Visit(Proto.getReturnLoc()))
3355 return true;
3356 }
3357 }
3358 break;
3359 }
3360
3361 case VisitorJob::PostChildrenVisitKind:
3362 if (PostChildrenVisitor(Parent, ClientData))
3363 return true;
3364 break;
3365 }
3366 }
3367 return false;
3368 }
3369
Visit(const Stmt * S)3370 bool CursorVisitor::Visit(const Stmt *S) {
3371 VisitorWorkList *WL = nullptr;
3372 if (!WorkListFreeList.empty()) {
3373 WL = WorkListFreeList.back();
3374 WL->clear();
3375 WorkListFreeList.pop_back();
3376 } else {
3377 WL = new VisitorWorkList();
3378 WorkListCache.push_back(WL);
3379 }
3380 EnqueueWorkList(*WL, S);
3381 bool result = RunVisitorWorkList(*WL);
3382 WorkListFreeList.push_back(WL);
3383 return result;
3384 }
3385
3386 namespace {
3387 typedef SmallVector<SourceRange, 4> RefNamePieces;
buildPieces(unsigned NameFlags,bool IsMemberRefExpr,const DeclarationNameInfo & NI,SourceRange QLoc,const SourceRange * TemplateArgsLoc=nullptr)3388 RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3389 const DeclarationNameInfo &NI, SourceRange QLoc,
3390 const SourceRange *TemplateArgsLoc = nullptr) {
3391 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3392 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3393 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
3394
3395 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
3396
3397 RefNamePieces Pieces;
3398
3399 if (WantQualifier && QLoc.isValid())
3400 Pieces.push_back(QLoc);
3401
3402 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3403 Pieces.push_back(NI.getLoc());
3404
3405 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3406 Pieces.push_back(*TemplateArgsLoc);
3407
3408 if (Kind == DeclarationName::CXXOperatorName) {
3409 Pieces.push_back(NI.getInfo().getCXXOperatorNameBeginLoc());
3410 Pieces.push_back(NI.getInfo().getCXXOperatorNameEndLoc());
3411 }
3412
3413 if (WantSinglePiece) {
3414 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3415 Pieces.clear();
3416 Pieces.push_back(R);
3417 }
3418
3419 return Pieces;
3420 }
3421 } // namespace
3422
3423 //===----------------------------------------------------------------------===//
3424 // Misc. API hooks.
3425 //===----------------------------------------------------------------------===//
3426
3427 namespace {
3428 struct RegisterFatalErrorHandler {
RegisterFatalErrorHandler__anon0fc279940511::RegisterFatalErrorHandler3429 RegisterFatalErrorHandler() {
3430 clang_install_aborting_llvm_fatal_error_handler();
3431 }
3432 };
3433 } // namespace
3434
3435 static llvm::ManagedStatic<RegisterFatalErrorHandler>
3436 RegisterFatalErrorHandlerOnce;
3437
clang_createIndex(int excludeDeclarationsFromPCH,int displayDiagnostics)3438 CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3439 int displayDiagnostics) {
3440 // We use crash recovery to make some of our APIs more reliable, implicitly
3441 // enable it.
3442 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3443 llvm::CrashRecoveryContext::Enable();
3444
3445 // Look through the managed static to trigger construction of the managed
3446 // static which registers our fatal error handler. This ensures it is only
3447 // registered once.
3448 (void)*RegisterFatalErrorHandlerOnce;
3449
3450 // Initialize targets for clang module support.
3451 llvm::InitializeAllTargets();
3452 llvm::InitializeAllTargetMCs();
3453 llvm::InitializeAllAsmPrinters();
3454 llvm::InitializeAllAsmParsers();
3455
3456 CIndexer *CIdxr = new CIndexer();
3457
3458 if (excludeDeclarationsFromPCH)
3459 CIdxr->setOnlyLocalDecls();
3460 if (displayDiagnostics)
3461 CIdxr->setDisplayDiagnostics();
3462
3463 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3464 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3465 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3466 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3467 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3468 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3469
3470 return CIdxr;
3471 }
3472
clang_disposeIndex(CXIndex CIdx)3473 void clang_disposeIndex(CXIndex CIdx) {
3474 if (CIdx)
3475 delete static_cast<CIndexer *>(CIdx);
3476 }
3477
clang_CXIndex_setGlobalOptions(CXIndex CIdx,unsigned options)3478 void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3479 if (CIdx)
3480 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3481 }
3482
clang_CXIndex_getGlobalOptions(CXIndex CIdx)3483 unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3484 if (CIdx)
3485 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3486 return 0;
3487 }
3488
clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,const char * Path)3489 void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
3490 const char *Path) {
3491 if (CIdx)
3492 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
3493 }
3494
clang_toggleCrashRecovery(unsigned isEnabled)3495 void clang_toggleCrashRecovery(unsigned isEnabled) {
3496 if (isEnabled)
3497 llvm::CrashRecoveryContext::Enable();
3498 else
3499 llvm::CrashRecoveryContext::Disable();
3500 }
3501
clang_createTranslationUnit(CXIndex CIdx,const char * ast_filename)3502 CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3503 const char *ast_filename) {
3504 CXTranslationUnit TU;
3505 enum CXErrorCode Result =
3506 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
3507 (void)Result;
3508 assert((TU && Result == CXError_Success) ||
3509 (!TU && Result != CXError_Success));
3510 return TU;
3511 }
3512
clang_createTranslationUnit2(CXIndex CIdx,const char * ast_filename,CXTranslationUnit * out_TU)3513 enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3514 const char *ast_filename,
3515 CXTranslationUnit *out_TU) {
3516 if (out_TU)
3517 *out_TU = nullptr;
3518
3519 if (!CIdx || !ast_filename || !out_TU)
3520 return CXError_InvalidArguments;
3521
3522 LOG_FUNC_SECTION { *Log << ast_filename; }
3523
3524 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3525 FileSystemOptions FileSystemOpts;
3526
3527 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3528 CompilerInstance::createDiagnostics(new DiagnosticOptions());
3529 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
3530 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
3531 ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3532 CXXIdx->getOnlyLocalDecls(), CaptureDiagsKind::All,
3533 /*AllowASTWithCompilerErrors=*/true,
3534 /*UserFilesAreVolatile=*/true);
3535 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
3536 return *out_TU ? CXError_Success : CXError_Failure;
3537 }
3538
clang_defaultEditingTranslationUnitOptions()3539 unsigned clang_defaultEditingTranslationUnitOptions() {
3540 return CXTranslationUnit_PrecompiledPreamble |
3541 CXTranslationUnit_CacheCompletionResults;
3542 }
3543
clang_createTranslationUnitFromSourceFile(CXIndex CIdx,const char * source_filename,int num_command_line_args,const char * const * command_line_args,unsigned num_unsaved_files,struct CXUnsavedFile * unsaved_files)3544 CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3545 CXIndex CIdx, const char *source_filename, int num_command_line_args,
3546 const char *const *command_line_args, unsigned num_unsaved_files,
3547 struct CXUnsavedFile *unsaved_files) {
3548 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3549 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3550 num_command_line_args, unsaved_files,
3551 num_unsaved_files, Options);
3552 }
3553
3554 static CXErrorCode
clang_parseTranslationUnit_Impl(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,ArrayRef<CXUnsavedFile> unsaved_files,unsigned options,CXTranslationUnit * out_TU)3555 clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3556 const char *const *command_line_args,
3557 int num_command_line_args,
3558 ArrayRef<CXUnsavedFile> unsaved_files,
3559 unsigned options, CXTranslationUnit *out_TU) {
3560 // Set up the initial return values.
3561 if (out_TU)
3562 *out_TU = nullptr;
3563
3564 // Check arguments.
3565 if (!CIdx || !out_TU)
3566 return CXError_InvalidArguments;
3567
3568 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3569
3570 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3571 setThreadBackgroundPriority();
3572
3573 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3574 bool CreatePreambleOnFirstParse =
3575 options & CXTranslationUnit_CreatePreambleOnFirstParse;
3576 // FIXME: Add a flag for modules.
3577 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3578 CXTranslationUnit_SingleFileParse))
3579 ? TU_Prefix
3580 : TU_Complete;
3581 bool CacheCodeCompletionResults =
3582 options & CXTranslationUnit_CacheCompletionResults;
3583 bool IncludeBriefCommentsInCodeCompletion =
3584 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3585 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
3586 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3587 bool RetainExcludedCB =
3588 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
3589 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
3590 if (options & CXTranslationUnit_SkipFunctionBodies) {
3591 SkipFunctionBodies =
3592 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
3593 ? SkipFunctionBodiesScope::Preamble
3594 : SkipFunctionBodiesScope::PreambleAndMainFile;
3595 }
3596
3597 // Configure the diagnostics.
3598 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3599 CompilerInstance::createDiagnostics(new DiagnosticOptions));
3600
3601 if (options & CXTranslationUnit_KeepGoing)
3602 Diags->setFatalsAsError(true);
3603
3604 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
3605 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
3606 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
3607
3608 // Recover resources if we crash before exiting this function.
3609 llvm::CrashRecoveryContextCleanupRegistrar<
3610 DiagnosticsEngine,
3611 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
3612 DiagCleanup(Diags.get());
3613
3614 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3615 new std::vector<ASTUnit::RemappedFile>());
3616
3617 // Recover resources if we crash before exiting this function.
3618 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3619 RemappedCleanup(RemappedFiles.get());
3620
3621 for (auto &UF : unsaved_files) {
3622 std::unique_ptr<llvm::MemoryBuffer> MB =
3623 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3624 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
3625 }
3626
3627 std::unique_ptr<std::vector<const char *>> Args(
3628 new std::vector<const char *>());
3629
3630 // Recover resources if we crash before exiting this method.
3631 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
3632 ArgsCleanup(Args.get());
3633
3634 // Since the Clang C library is primarily used by batch tools dealing with
3635 // (often very broken) source code, where spell-checking can have a
3636 // significant negative impact on performance (particularly when
3637 // precompiled headers are involved), we disable it by default.
3638 // Only do this if we haven't found a spell-checking-related argument.
3639 bool FoundSpellCheckingArgument = false;
3640 for (int I = 0; I != num_command_line_args; ++I) {
3641 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3642 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3643 FoundSpellCheckingArgument = true;
3644 break;
3645 }
3646 }
3647 Args->insert(Args->end(), command_line_args,
3648 command_line_args + num_command_line_args);
3649
3650 if (!FoundSpellCheckingArgument)
3651 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3652
3653 // The 'source_filename' argument is optional. If the caller does not
3654 // specify it then it is assumed that the source file is specified
3655 // in the actual argument list.
3656 // Put the source file after command_line_args otherwise if '-x' flag is
3657 // present it will be unused.
3658 if (source_filename)
3659 Args->push_back(source_filename);
3660
3661 // Do we need the detailed preprocessing record?
3662 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3663 Args->push_back("-Xclang");
3664 Args->push_back("-detailed-preprocessing-record");
3665 }
3666
3667 // Suppress any editor placeholder diagnostics.
3668 Args->push_back("-fallow-editor-placeholders");
3669
3670 unsigned NumErrors = Diags->getClient()->getNumErrors();
3671 std::unique_ptr<ASTUnit> ErrUnit;
3672 // Unless the user specified that they want the preamble on the first parse
3673 // set it up to be created on the first reparse. This makes the first parse
3674 // faster, trading for a slower (first) reparse.
3675 unsigned PrecompilePreambleAfterNParses =
3676 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
3677
3678 LibclangInvocationReporter InvocationReporter(
3679 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
3680 options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
3681 unsaved_files);
3682 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
3683 Args->data(), Args->data() + Args->size(),
3684 CXXIdx->getPCHContainerOperations(), Diags,
3685 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3686 CaptureDiagnostics, *RemappedFiles.get(),
3687 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3688 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3689 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
3690 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
3691 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3692 &ErrUnit));
3693
3694 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
3695 if (!Unit && !ErrUnit)
3696 return CXError_ASTReadError;
3697
3698 if (NumErrors != Diags->getClient()->getNumErrors()) {
3699 // Make sure to check that 'Unit' is non-NULL.
3700 if (CXXIdx->getDisplayDiagnostics())
3701 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3702 }
3703
3704 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3705 return CXError_ASTReadError;
3706
3707 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
3708 if (CXTranslationUnitImpl *TU = *out_TU) {
3709 TU->ParsingOptions = options;
3710 TU->Arguments.reserve(Args->size());
3711 for (const char *Arg : *Args)
3712 TU->Arguments.push_back(Arg);
3713 return CXError_Success;
3714 }
3715 return CXError_Failure;
3716 }
3717
3718 CXTranslationUnit
clang_parseTranslationUnit(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,struct CXUnsavedFile * unsaved_files,unsigned num_unsaved_files,unsigned options)3719 clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
3720 const char *const *command_line_args,
3721 int num_command_line_args,
3722 struct CXUnsavedFile *unsaved_files,
3723 unsigned num_unsaved_files, unsigned options) {
3724 CXTranslationUnit TU;
3725 enum CXErrorCode Result = clang_parseTranslationUnit2(
3726 CIdx, source_filename, command_line_args, num_command_line_args,
3727 unsaved_files, num_unsaved_files, options, &TU);
3728 (void)Result;
3729 assert((TU && Result == CXError_Success) ||
3730 (!TU && Result != CXError_Success));
3731 return TU;
3732 }
3733
clang_parseTranslationUnit2(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,struct CXUnsavedFile * unsaved_files,unsigned num_unsaved_files,unsigned options,CXTranslationUnit * out_TU)3734 enum CXErrorCode clang_parseTranslationUnit2(
3735 CXIndex CIdx, const char *source_filename,
3736 const char *const *command_line_args, int num_command_line_args,
3737 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3738 unsigned options, CXTranslationUnit *out_TU) {
3739 noteBottomOfStack();
3740 SmallVector<const char *, 4> Args;
3741 Args.push_back("clang");
3742 Args.append(command_line_args, command_line_args + num_command_line_args);
3743 return clang_parseTranslationUnit2FullArgv(
3744 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3745 num_unsaved_files, options, out_TU);
3746 }
3747
clang_parseTranslationUnit2FullArgv(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,struct CXUnsavedFile * unsaved_files,unsigned num_unsaved_files,unsigned options,CXTranslationUnit * out_TU)3748 enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3749 CXIndex CIdx, const char *source_filename,
3750 const char *const *command_line_args, int num_command_line_args,
3751 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3752 unsigned options, CXTranslationUnit *out_TU) {
3753 LOG_FUNC_SECTION {
3754 *Log << source_filename << ": ";
3755 for (int i = 0; i != num_command_line_args; ++i)
3756 *Log << command_line_args[i] << " ";
3757 }
3758
3759 if (num_unsaved_files && !unsaved_files)
3760 return CXError_InvalidArguments;
3761
3762 CXErrorCode result = CXError_Failure;
3763 auto ParseTranslationUnitImpl = [=, &result] {
3764 noteBottomOfStack();
3765 result = clang_parseTranslationUnit_Impl(
3766 CIdx, source_filename, command_line_args, num_command_line_args,
3767 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3768 };
3769
3770 llvm::CrashRecoveryContext CRC;
3771
3772 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
3773 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3774 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3775 fprintf(stderr, " 'command_line_args' : [");
3776 for (int i = 0; i != num_command_line_args; ++i) {
3777 if (i)
3778 fprintf(stderr, ", ");
3779 fprintf(stderr, "'%s'", command_line_args[i]);
3780 }
3781 fprintf(stderr, "],\n");
3782 fprintf(stderr, " 'unsaved_files' : [");
3783 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3784 if (i)
3785 fprintf(stderr, ", ");
3786 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3787 unsaved_files[i].Length);
3788 }
3789 fprintf(stderr, "],\n");
3790 fprintf(stderr, " 'options' : %d,\n", options);
3791 fprintf(stderr, "}\n");
3792
3793 return CXError_Crashed;
3794 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3795 if (CXTranslationUnit *TU = out_TU)
3796 PrintLibclangResourceUsage(*TU);
3797 }
3798
3799 return result;
3800 }
3801
clang_Type_getObjCEncoding(CXType CT)3802 CXString clang_Type_getObjCEncoding(CXType CT) {
3803 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3804 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3805 std::string encoding;
3806 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
3807
3808 return cxstring::createDup(encoding);
3809 }
3810
getMacroIdentifier(CXCursor C)3811 static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3812 if (C.kind == CXCursor_MacroDefinition) {
3813 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3814 return MDR->getName();
3815 } else if (C.kind == CXCursor_MacroExpansion) {
3816 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3817 return ME.getName();
3818 }
3819 return nullptr;
3820 }
3821
clang_Cursor_isMacroFunctionLike(CXCursor C)3822 unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3823 const IdentifierInfo *II = getMacroIdentifier(C);
3824 if (!II) {
3825 return false;
3826 }
3827 ASTUnit *ASTU = getCursorASTUnit(C);
3828 Preprocessor &PP = ASTU->getPreprocessor();
3829 if (const MacroInfo *MI = PP.getMacroInfo(II))
3830 return MI->isFunctionLike();
3831 return false;
3832 }
3833
clang_Cursor_isMacroBuiltin(CXCursor C)3834 unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3835 const IdentifierInfo *II = getMacroIdentifier(C);
3836 if (!II) {
3837 return false;
3838 }
3839 ASTUnit *ASTU = getCursorASTUnit(C);
3840 Preprocessor &PP = ASTU->getPreprocessor();
3841 if (const MacroInfo *MI = PP.getMacroInfo(II))
3842 return MI->isBuiltinMacro();
3843 return false;
3844 }
3845
clang_Cursor_isFunctionInlined(CXCursor C)3846 unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3847 const Decl *D = getCursorDecl(C);
3848 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3849 if (!FD) {
3850 return false;
3851 }
3852 return FD->isInlined();
3853 }
3854
getCFSTR_value(CallExpr * callExpr)3855 static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
3856 if (callExpr->getNumArgs() != 1) {
3857 return nullptr;
3858 }
3859
3860 StringLiteral *S = nullptr;
3861 auto *arg = callExpr->getArg(0);
3862 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3863 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3864 auto *subExpr = I->getSubExprAsWritten();
3865
3866 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
3867 return nullptr;
3868 }
3869
3870 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3871 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3872 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3873 } else {
3874 return nullptr;
3875 }
3876 return S;
3877 }
3878
3879 struct ExprEvalResult {
3880 CXEvalResultKind EvalType;
3881 union {
3882 unsigned long long unsignedVal;
3883 long long intVal;
3884 double floatVal;
3885 char *stringVal;
3886 } EvalData;
3887 bool IsUnsignedInt;
~ExprEvalResultExprEvalResult3888 ~ExprEvalResult() {
3889 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3890 EvalType != CXEval_Int) {
3891 delete[] EvalData.stringVal;
3892 }
3893 }
3894 };
3895
clang_EvalResult_dispose(CXEvalResult E)3896 void clang_EvalResult_dispose(CXEvalResult E) {
3897 delete static_cast<ExprEvalResult *>(E);
3898 }
3899
clang_EvalResult_getKind(CXEvalResult E)3900 CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3901 if (!E) {
3902 return CXEval_UnExposed;
3903 }
3904 return ((ExprEvalResult *)E)->EvalType;
3905 }
3906
clang_EvalResult_getAsInt(CXEvalResult E)3907 int clang_EvalResult_getAsInt(CXEvalResult E) {
3908 return clang_EvalResult_getAsLongLong(E);
3909 }
3910
clang_EvalResult_getAsLongLong(CXEvalResult E)3911 long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
3912 if (!E) {
3913 return 0;
3914 }
3915 ExprEvalResult *Result = (ExprEvalResult *)E;
3916 if (Result->IsUnsignedInt)
3917 return Result->EvalData.unsignedVal;
3918 return Result->EvalData.intVal;
3919 }
3920
clang_EvalResult_isUnsignedInt(CXEvalResult E)3921 unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
3922 return ((ExprEvalResult *)E)->IsUnsignedInt;
3923 }
3924
clang_EvalResult_getAsUnsigned(CXEvalResult E)3925 unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
3926 if (!E) {
3927 return 0;
3928 }
3929
3930 ExprEvalResult *Result = (ExprEvalResult *)E;
3931 if (Result->IsUnsignedInt)
3932 return Result->EvalData.unsignedVal;
3933 return Result->EvalData.intVal;
3934 }
3935
clang_EvalResult_getAsDouble(CXEvalResult E)3936 double clang_EvalResult_getAsDouble(CXEvalResult E) {
3937 if (!E) {
3938 return 0;
3939 }
3940 return ((ExprEvalResult *)E)->EvalData.floatVal;
3941 }
3942
clang_EvalResult_getAsStr(CXEvalResult E)3943 const char *clang_EvalResult_getAsStr(CXEvalResult E) {
3944 if (!E) {
3945 return nullptr;
3946 }
3947 return ((ExprEvalResult *)E)->EvalData.stringVal;
3948 }
3949
evaluateExpr(Expr * expr,CXCursor C)3950 static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
3951 Expr::EvalResult ER;
3952 ASTContext &ctx = getCursorContext(C);
3953 if (!expr)
3954 return nullptr;
3955
3956 expr = expr->IgnoreParens();
3957 if (expr->isValueDependent())
3958 return nullptr;
3959 if (!expr->EvaluateAsRValue(ER, ctx))
3960 return nullptr;
3961
3962 QualType rettype;
3963 CallExpr *callExpr;
3964 auto result = std::make_unique<ExprEvalResult>();
3965 result->EvalType = CXEval_UnExposed;
3966 result->IsUnsignedInt = false;
3967
3968 if (ER.Val.isInt()) {
3969 result->EvalType = CXEval_Int;
3970
3971 auto &val = ER.Val.getInt();
3972 if (val.isUnsigned()) {
3973 result->IsUnsignedInt = true;
3974 result->EvalData.unsignedVal = val.getZExtValue();
3975 } else {
3976 result->EvalData.intVal = val.getExtValue();
3977 }
3978
3979 return result.release();
3980 }
3981
3982 if (ER.Val.isFloat()) {
3983 llvm::SmallVector<char, 100> Buffer;
3984 ER.Val.getFloat().toString(Buffer);
3985 std::string floatStr(Buffer.data(), Buffer.size());
3986 result->EvalType = CXEval_Float;
3987 bool ignored;
3988 llvm::APFloat apFloat = ER.Val.getFloat();
3989 apFloat.convert(llvm::APFloat::IEEEdouble(),
3990 llvm::APFloat::rmNearestTiesToEven, &ignored);
3991 result->EvalData.floatVal = apFloat.convertToDouble();
3992 return result.release();
3993 }
3994
3995 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3996 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3997 auto *subExpr = I->getSubExprAsWritten();
3998 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3999 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
4000 const StringLiteral *StrE = nullptr;
4001 const ObjCStringLiteral *ObjCExpr;
4002 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
4003
4004 if (ObjCExpr) {
4005 StrE = ObjCExpr->getString();
4006 result->EvalType = CXEval_ObjCStrLiteral;
4007 } else {
4008 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
4009 result->EvalType = CXEval_StrLiteral;
4010 }
4011
4012 std::string strRef(StrE->getString().str());
4013 result->EvalData.stringVal = new char[strRef.size() + 1];
4014 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
4015 strRef.size());
4016 result->EvalData.stringVal[strRef.size()] = '\0';
4017 return result.release();
4018 }
4019 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
4020 expr->getStmtClass() == Stmt::StringLiteralClass) {
4021 const StringLiteral *StrE = nullptr;
4022 const ObjCStringLiteral *ObjCExpr;
4023 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
4024
4025 if (ObjCExpr) {
4026 StrE = ObjCExpr->getString();
4027 result->EvalType = CXEval_ObjCStrLiteral;
4028 } else {
4029 StrE = cast<StringLiteral>(expr);
4030 result->EvalType = CXEval_StrLiteral;
4031 }
4032
4033 std::string strRef(StrE->getString().str());
4034 result->EvalData.stringVal = new char[strRef.size() + 1];
4035 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
4036 result->EvalData.stringVal[strRef.size()] = '\0';
4037 return result.release();
4038 }
4039
4040 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
4041 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
4042
4043 rettype = CC->getType();
4044 if (rettype.getAsString() == "CFStringRef" &&
4045 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
4046
4047 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
4048 StringLiteral *S = getCFSTR_value(callExpr);
4049 if (S) {
4050 std::string strLiteral(S->getString().str());
4051 result->EvalType = CXEval_CFStr;
4052
4053 result->EvalData.stringVal = new char[strLiteral.size() + 1];
4054 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
4055 strLiteral.size());
4056 result->EvalData.stringVal[strLiteral.size()] = '\0';
4057 return result.release();
4058 }
4059 }
4060
4061 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
4062 callExpr = static_cast<CallExpr *>(expr);
4063 rettype = callExpr->getCallReturnType(ctx);
4064
4065 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
4066 return nullptr;
4067
4068 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
4069 if (callExpr->getNumArgs() == 1 &&
4070 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
4071 return nullptr;
4072 } else if (rettype.getAsString() == "CFStringRef") {
4073
4074 StringLiteral *S = getCFSTR_value(callExpr);
4075 if (S) {
4076 std::string strLiteral(S->getString().str());
4077 result->EvalType = CXEval_CFStr;
4078 result->EvalData.stringVal = new char[strLiteral.size() + 1];
4079 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
4080 strLiteral.size());
4081 result->EvalData.stringVal[strLiteral.size()] = '\0';
4082 return result.release();
4083 }
4084 }
4085 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
4086 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
4087 ValueDecl *V = D->getDecl();
4088 if (V->getKind() == Decl::Function) {
4089 std::string strName = V->getNameAsString();
4090 result->EvalType = CXEval_Other;
4091 result->EvalData.stringVal = new char[strName.size() + 1];
4092 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
4093 result->EvalData.stringVal[strName.size()] = '\0';
4094 return result.release();
4095 }
4096 }
4097
4098 return nullptr;
4099 }
4100
evaluateDeclExpr(const Decl * D)4101 static const Expr *evaluateDeclExpr(const Decl *D) {
4102 if (!D)
4103 return nullptr;
4104 if (auto *Var = dyn_cast<VarDecl>(D))
4105 return Var->getInit();
4106 else if (auto *Field = dyn_cast<FieldDecl>(D))
4107 return Field->getInClassInitializer();
4108 return nullptr;
4109 }
4110
evaluateCompoundStmtExpr(const CompoundStmt * CS)4111 static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4112 assert(CS && "invalid compound statement");
4113 for (auto *bodyIterator : CS->body()) {
4114 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4115 return E;
4116 }
4117 return nullptr;
4118 }
4119
clang_Cursor_Evaluate(CXCursor C)4120 CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
4121 const Expr *E = nullptr;
4122 if (clang_getCursorKind(C) == CXCursor_CompoundStmt)
4123 E = evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)));
4124 else if (clang_isDeclaration(C.kind))
4125 E = evaluateDeclExpr(getCursorDecl(C));
4126 else if (clang_isExpression(C.kind))
4127 E = getCursorExpr(C);
4128 if (E)
4129 return const_cast<CXEvalResult>(
4130 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4131 return nullptr;
4132 }
4133
clang_Cursor_hasAttrs(CXCursor C)4134 unsigned clang_Cursor_hasAttrs(CXCursor C) {
4135 const Decl *D = getCursorDecl(C);
4136 if (!D) {
4137 return 0;
4138 }
4139
4140 if (D->hasAttrs()) {
4141 return 1;
4142 }
4143
4144 return 0;
4145 }
clang_defaultSaveOptions(CXTranslationUnit TU)4146 unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4147 return CXSaveTranslationUnit_None;
4148 }
4149
clang_saveTranslationUnit_Impl(CXTranslationUnit TU,const char * FileName,unsigned options)4150 static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4151 const char *FileName,
4152 unsigned options) {
4153 CIndexer *CXXIdx = TU->CIdx;
4154 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4155 setThreadBackgroundPriority();
4156
4157 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4158 return hadError ? CXSaveError_Unknown : CXSaveError_None;
4159 }
4160
clang_saveTranslationUnit(CXTranslationUnit TU,const char * FileName,unsigned options)4161 int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4162 unsigned options) {
4163 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
4164
4165 if (isNotUsableTU(TU)) {
4166 LOG_BAD_TU(TU);
4167 return CXSaveError_InvalidTU;
4168 }
4169
4170 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4171 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4172 if (!CXXUnit->hasSema())
4173 return CXSaveError_InvalidTU;
4174
4175 CXSaveError result;
4176 auto SaveTranslationUnitImpl = [=, &result]() {
4177 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4178 };
4179
4180 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
4181 SaveTranslationUnitImpl();
4182
4183 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4184 PrintLibclangResourceUsage(TU);
4185
4186 return result;
4187 }
4188
4189 // We have an AST that has invalid nodes due to compiler errors.
4190 // Use a crash recovery thread for protection.
4191
4192 llvm::CrashRecoveryContext CRC;
4193
4194 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
4195 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4196 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4197 fprintf(stderr, " 'options' : %d,\n", options);
4198 fprintf(stderr, "}\n");
4199
4200 return CXSaveError_Unknown;
4201
4202 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4203 PrintLibclangResourceUsage(TU);
4204 }
4205
4206 return result;
4207 }
4208
clang_disposeTranslationUnit(CXTranslationUnit CTUnit)4209 void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4210 if (CTUnit) {
4211 // If the translation unit has been marked as unsafe to free, just discard
4212 // it.
4213 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4214 if (Unit && Unit->isUnsafeToFree())
4215 return;
4216
4217 delete cxtu::getASTUnit(CTUnit);
4218 delete CTUnit->StringPool;
4219 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4220 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
4221 delete CTUnit->CommentToXML;
4222 delete CTUnit;
4223 }
4224 }
4225
clang_suspendTranslationUnit(CXTranslationUnit CTUnit)4226 unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4227 if (CTUnit) {
4228 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4229
4230 if (Unit && Unit->isUnsafeToFree())
4231 return false;
4232
4233 Unit->ResetForParse();
4234 return true;
4235 }
4236
4237 return false;
4238 }
4239
clang_defaultReparseOptions(CXTranslationUnit TU)4240 unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4241 return CXReparse_None;
4242 }
4243
4244 static CXErrorCode
clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,ArrayRef<CXUnsavedFile> unsaved_files,unsigned options)4245 clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4246 ArrayRef<CXUnsavedFile> unsaved_files,
4247 unsigned options) {
4248 // Check arguments.
4249 if (isNotUsableTU(TU)) {
4250 LOG_BAD_TU(TU);
4251 return CXError_InvalidArguments;
4252 }
4253
4254 // Reset the associated diagnostics.
4255 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
4256 TU->Diagnostics = nullptr;
4257
4258 CIndexer *CXXIdx = TU->CIdx;
4259 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4260 setThreadBackgroundPriority();
4261
4262 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4263 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4264
4265 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4266 new std::vector<ASTUnit::RemappedFile>());
4267
4268 // Recover resources if we crash before exiting this function.
4269 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4270 RemappedCleanup(RemappedFiles.get());
4271
4272 for (auto &UF : unsaved_files) {
4273 std::unique_ptr<llvm::MemoryBuffer> MB =
4274 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
4275 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
4276 }
4277
4278 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4279 *RemappedFiles.get()))
4280 return CXError_Success;
4281 if (isASTReadError(CXXUnit))
4282 return CXError_ASTReadError;
4283 return CXError_Failure;
4284 }
4285
clang_reparseTranslationUnit(CXTranslationUnit TU,unsigned num_unsaved_files,struct CXUnsavedFile * unsaved_files,unsigned options)4286 int clang_reparseTranslationUnit(CXTranslationUnit TU,
4287 unsigned num_unsaved_files,
4288 struct CXUnsavedFile *unsaved_files,
4289 unsigned options) {
4290 LOG_FUNC_SECTION { *Log << TU; }
4291
4292 if (num_unsaved_files && !unsaved_files)
4293 return CXError_InvalidArguments;
4294
4295 CXErrorCode result;
4296 auto ReparseTranslationUnitImpl = [=, &result]() {
4297 result = clang_reparseTranslationUnit_Impl(
4298 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
4299 };
4300
4301 llvm::CrashRecoveryContext CRC;
4302
4303 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
4304 fprintf(stderr, "libclang: crash detected during reparsing\n");
4305 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
4306 return CXError_Crashed;
4307 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4308 PrintLibclangResourceUsage(TU);
4309
4310 return result;
4311 }
4312
clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit)4313 CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
4314 if (isNotUsableTU(CTUnit)) {
4315 LOG_BAD_TU(CTUnit);
4316 return cxstring::createEmpty();
4317 }
4318
4319 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4320 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
4321 }
4322
clang_getTranslationUnitCursor(CXTranslationUnit TU)4323 CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
4324 if (isNotUsableTU(TU)) {
4325 LOG_BAD_TU(TU);
4326 return clang_getNullCursor();
4327 }
4328
4329 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4330 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4331 }
4332
clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit)4333 CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4334 if (isNotUsableTU(CTUnit)) {
4335 LOG_BAD_TU(CTUnit);
4336 return nullptr;
4337 }
4338
4339 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
4340 impl->TranslationUnit = CTUnit;
4341 return impl;
4342 }
4343
clang_TargetInfo_getTriple(CXTargetInfo TargetInfo)4344 CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4345 if (!TargetInfo)
4346 return cxstring::createEmpty();
4347
4348 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4349 assert(!isNotUsableTU(CTUnit) &&
4350 "Unexpected unusable translation unit in TargetInfo");
4351
4352 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4353 std::string Triple =
4354 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
4355 return cxstring::createDup(Triple);
4356 }
4357
clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo)4358 int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4359 if (!TargetInfo)
4360 return -1;
4361
4362 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4363 assert(!isNotUsableTU(CTUnit) &&
4364 "Unexpected unusable translation unit in TargetInfo");
4365
4366 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4367 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4368 }
4369
clang_TargetInfo_dispose(CXTargetInfo TargetInfo)4370 void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4371 if (!TargetInfo)
4372 return;
4373
4374 delete TargetInfo;
4375 }
4376
4377 //===----------------------------------------------------------------------===//
4378 // CXFile Operations.
4379 //===----------------------------------------------------------------------===//
4380
clang_getFileName(CXFile SFile)4381 CXString clang_getFileName(CXFile SFile) {
4382 if (!SFile)
4383 return cxstring::createNull();
4384
4385 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4386 return cxstring::createRef(FEnt->getName());
4387 }
4388
clang_getFileTime(CXFile SFile)4389 time_t clang_getFileTime(CXFile SFile) {
4390 if (!SFile)
4391 return 0;
4392
4393 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4394 return FEnt->getModificationTime();
4395 }
4396
clang_getFile(CXTranslationUnit TU,const char * file_name)4397 CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
4398 if (isNotUsableTU(TU)) {
4399 LOG_BAD_TU(TU);
4400 return nullptr;
4401 }
4402
4403 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4404
4405 FileManager &FMgr = CXXUnit->getFileManager();
4406 auto File = FMgr.getFile(file_name);
4407 if (!File)
4408 return nullptr;
4409 return const_cast<FileEntry *>(*File);
4410 }
4411
clang_getFileContents(CXTranslationUnit TU,CXFile file,size_t * size)4412 const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4413 size_t *size) {
4414 if (isNotUsableTU(TU)) {
4415 LOG_BAD_TU(TU);
4416 return nullptr;
4417 }
4418
4419 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4420 FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
4421 llvm::Optional<llvm::MemoryBufferRef> buf = SM.getBufferOrNone(fid);
4422 if (!buf) {
4423 if (size)
4424 *size = 0;
4425 return nullptr;
4426 }
4427 if (size)
4428 *size = buf->getBufferSize();
4429 return buf->getBufferStart();
4430 }
4431
clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,CXFile file)4432 unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
4433 if (isNotUsableTU(TU)) {
4434 LOG_BAD_TU(TU);
4435 return 0;
4436 }
4437
4438 if (!file)
4439 return 0;
4440
4441 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4442 FileEntry *FEnt = static_cast<FileEntry *>(file);
4443 return CXXUnit->getPreprocessor()
4444 .getHeaderSearchInfo()
4445 .isFileMultipleIncludeGuarded(FEnt);
4446 }
4447
clang_getFileUniqueID(CXFile file,CXFileUniqueID * outID)4448 int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
4449 if (!file || !outID)
4450 return 1;
4451
4452 FileEntry *FEnt = static_cast<FileEntry *>(file);
4453 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
4454 outID->data[0] = ID.getDevice();
4455 outID->data[1] = ID.getFile();
4456 outID->data[2] = FEnt->getModificationTime();
4457 return 0;
4458 }
4459
clang_File_isEqual(CXFile file1,CXFile file2)4460 int clang_File_isEqual(CXFile file1, CXFile file2) {
4461 if (file1 == file2)
4462 return true;
4463
4464 if (!file1 || !file2)
4465 return false;
4466
4467 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
4468 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
4469 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
4470 }
4471
clang_File_tryGetRealPathName(CXFile SFile)4472 CXString clang_File_tryGetRealPathName(CXFile SFile) {
4473 if (!SFile)
4474 return cxstring::createNull();
4475
4476 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4477 return cxstring::createRef(FEnt->tryGetRealPathName());
4478 }
4479
4480 //===----------------------------------------------------------------------===//
4481 // CXCursor Operations.
4482 //===----------------------------------------------------------------------===//
4483
getDeclFromExpr(const Stmt * E)4484 static const Decl *getDeclFromExpr(const Stmt *E) {
4485 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
4486 return getDeclFromExpr(CE->getSubExpr());
4487
4488 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
4489 return RefExpr->getDecl();
4490 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
4491 return ME->getMemberDecl();
4492 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
4493 return RE->getDecl();
4494 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
4495 if (PRE->isExplicitProperty())
4496 return PRE->getExplicitProperty();
4497 // It could be messaging both getter and setter as in:
4498 // ++myobj.myprop;
4499 // in which case prefer to associate the setter since it is less obvious
4500 // from inspecting the source that the setter is going to get called.
4501 if (PRE->isMessagingSetter())
4502 return PRE->getImplicitPropertySetter();
4503 return PRE->getImplicitPropertyGetter();
4504 }
4505 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
4506 return getDeclFromExpr(POE->getSyntacticForm());
4507 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
4508 if (Expr *Src = OVE->getSourceExpr())
4509 return getDeclFromExpr(Src);
4510
4511 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
4512 return getDeclFromExpr(CE->getCallee());
4513 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
4514 if (!CE->isElidable())
4515 return CE->getConstructor();
4516 if (const CXXInheritedCtorInitExpr *CE =
4517 dyn_cast<CXXInheritedCtorInitExpr>(E))
4518 return CE->getConstructor();
4519 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
4520 return OME->getMethodDecl();
4521
4522 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
4523 return PE->getProtocol();
4524 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4525 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
4526 return NTTP->getParameterPack();
4527 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
4528 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
4529 isa<ParmVarDecl>(SizeOfPack->getPack()))
4530 return SizeOfPack->getPack();
4531
4532 return nullptr;
4533 }
4534
getLocationFromExpr(const Expr * E)4535 static SourceLocation getLocationFromExpr(const Expr *E) {
4536 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
4537 return getLocationFromExpr(CE->getSubExpr());
4538
4539 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
4540 return /*FIXME:*/ Msg->getLeftLoc();
4541 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
4542 return DRE->getLocation();
4543 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
4544 return Member->getMemberLoc();
4545 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
4546 return Ivar->getLocation();
4547 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
4548 return SizeOfPack->getPackLoc();
4549 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
4550 return PropRef->getLocation();
4551
4552 return E->getBeginLoc();
4553 }
4554
4555 extern "C" {
4556
clang_visitChildren(CXCursor parent,CXCursorVisitor visitor,CXClientData client_data)4557 unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
4558 CXClientData client_data) {
4559 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4560 /*VisitPreprocessorLast=*/false);
4561 return CursorVis.VisitChildren(parent);
4562 }
4563
4564 #ifndef __has_feature
4565 #define __has_feature(x) 0
4566 #endif
4567 #if __has_feature(blocks)
4568 typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4569 CXCursor parent);
4570
4571 static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4572 CXClientData client_data) {
4573 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4574 return block(cursor, parent);
4575 }
4576 #else
4577 // If we are compiled with a compiler that doesn't have native blocks support,
4578 // define and call the block manually, so the
4579 typedef struct _CXChildVisitResult {
4580 void *isa;
4581 int flags;
4582 int reserved;
4583 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
4584 CXCursor);
4585 } * CXCursorVisitorBlock;
4586
4587 static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4588 CXClientData client_data) {
4589 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4590 return block->invoke(block, cursor, parent);
4591 }
4592 #endif
4593
4594 unsigned clang_visitChildrenWithBlock(CXCursor parent,
4595 CXCursorVisitorBlock block) {
4596 return clang_visitChildren(parent, visitWithBlock, block);
4597 }
4598
4599 static CXString getDeclSpelling(const Decl *D) {
4600 if (!D)
4601 return cxstring::createEmpty();
4602
4603 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
4604 if (!ND) {
4605 if (const ObjCPropertyImplDecl *PropImpl =
4606 dyn_cast<ObjCPropertyImplDecl>(D))
4607 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4608 return cxstring::createDup(Property->getIdentifier()->getName());
4609
4610 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
4611 if (Module *Mod = ImportD->getImportedModule())
4612 return cxstring::createDup(Mod->getFullModuleName());
4613
4614 return cxstring::createEmpty();
4615 }
4616
4617 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
4618 return cxstring::createDup(OMD->getSelector().getAsString());
4619
4620 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
4621 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4622 // and returns different names. NamedDecl returns the class name and
4623 // ObjCCategoryImplDecl returns the category name.
4624 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
4625
4626 if (isa<UsingDirectiveDecl>(D))
4627 return cxstring::createEmpty();
4628
4629 SmallString<1024> S;
4630 llvm::raw_svector_ostream os(S);
4631 ND->printName(os);
4632
4633 return cxstring::createDup(os.str());
4634 }
4635
4636 CXString clang_getCursorSpelling(CXCursor C) {
4637 if (clang_isTranslationUnit(C.kind))
4638 return clang_getTranslationUnitSpelling(getCursorTU(C));
4639
4640 if (clang_isReference(C.kind)) {
4641 switch (C.kind) {
4642 case CXCursor_ObjCSuperClassRef: {
4643 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
4644 return cxstring::createRef(Super->getIdentifier()->getNameStart());
4645 }
4646 case CXCursor_ObjCClassRef: {
4647 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4648 return cxstring::createRef(Class->getIdentifier()->getNameStart());
4649 }
4650 case CXCursor_ObjCProtocolRef: {
4651 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
4652 assert(OID && "getCursorSpelling(): Missing protocol decl");
4653 return cxstring::createRef(OID->getIdentifier()->getNameStart());
4654 }
4655 case CXCursor_CXXBaseSpecifier: {
4656 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
4657 return cxstring::createDup(B->getType().getAsString());
4658 }
4659 case CXCursor_TypeRef: {
4660 const TypeDecl *Type = getCursorTypeRef(C).first;
4661 assert(Type && "Missing type decl");
4662
4663 return cxstring::createDup(
4664 getCursorContext(C).getTypeDeclType(Type).getAsString());
4665 }
4666 case CXCursor_TemplateRef: {
4667 const TemplateDecl *Template = getCursorTemplateRef(C).first;
4668 assert(Template && "Missing template decl");
4669
4670 return cxstring::createDup(Template->getNameAsString());
4671 }
4672
4673 case CXCursor_NamespaceRef: {
4674 const NamedDecl *NS = getCursorNamespaceRef(C).first;
4675 assert(NS && "Missing namespace decl");
4676
4677 return cxstring::createDup(NS->getNameAsString());
4678 }
4679
4680 case CXCursor_MemberRef: {
4681 const FieldDecl *Field = getCursorMemberRef(C).first;
4682 assert(Field && "Missing member decl");
4683
4684 return cxstring::createDup(Field->getNameAsString());
4685 }
4686
4687 case CXCursor_LabelRef: {
4688 const LabelStmt *Label = getCursorLabelRef(C).first;
4689 assert(Label && "Missing label");
4690
4691 return cxstring::createRef(Label->getName());
4692 }
4693
4694 case CXCursor_OverloadedDeclRef: {
4695 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4696 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4697 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
4698 return cxstring::createDup(ND->getNameAsString());
4699 return cxstring::createEmpty();
4700 }
4701 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
4702 return cxstring::createDup(E->getName().getAsString());
4703 OverloadedTemplateStorage *Ovl =
4704 Storage.get<OverloadedTemplateStorage *>();
4705 if (Ovl->size() == 0)
4706 return cxstring::createEmpty();
4707 return cxstring::createDup((*Ovl->begin())->getNameAsString());
4708 }
4709
4710 case CXCursor_VariableRef: {
4711 const VarDecl *Var = getCursorVariableRef(C).first;
4712 assert(Var && "Missing variable decl");
4713
4714 return cxstring::createDup(Var->getNameAsString());
4715 }
4716
4717 default:
4718 return cxstring::createRef("<not implemented>");
4719 }
4720 }
4721
4722 if (clang_isExpression(C.kind)) {
4723 const Expr *E = getCursorExpr(C);
4724
4725 if (C.kind == CXCursor_ObjCStringLiteral ||
4726 C.kind == CXCursor_StringLiteral) {
4727 const StringLiteral *SLit;
4728 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4729 SLit = OSL->getString();
4730 } else {
4731 SLit = cast<StringLiteral>(E);
4732 }
4733 SmallString<256> Buf;
4734 llvm::raw_svector_ostream OS(Buf);
4735 SLit->outputString(OS);
4736 return cxstring::createDup(OS.str());
4737 }
4738
4739 const Decl *D = getDeclFromExpr(getCursorExpr(C));
4740 if (D)
4741 return getDeclSpelling(D);
4742 return cxstring::createEmpty();
4743 }
4744
4745 if (clang_isStatement(C.kind)) {
4746 const Stmt *S = getCursorStmt(C);
4747 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
4748 return cxstring::createRef(Label->getName());
4749
4750 return cxstring::createEmpty();
4751 }
4752
4753 if (C.kind == CXCursor_MacroExpansion)
4754 return cxstring::createRef(
4755 getCursorMacroExpansion(C).getName()->getNameStart());
4756
4757 if (C.kind == CXCursor_MacroDefinition)
4758 return cxstring::createRef(
4759 getCursorMacroDefinition(C)->getName()->getNameStart());
4760
4761 if (C.kind == CXCursor_InclusionDirective)
4762 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
4763
4764 if (clang_isDeclaration(C.kind))
4765 return getDeclSpelling(getCursorDecl(C));
4766
4767 if (C.kind == CXCursor_AnnotateAttr) {
4768 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
4769 return cxstring::createDup(AA->getAnnotation());
4770 }
4771
4772 if (C.kind == CXCursor_AsmLabelAttr) {
4773 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
4774 return cxstring::createDup(AA->getLabel());
4775 }
4776
4777 if (C.kind == CXCursor_PackedAttr) {
4778 return cxstring::createRef("packed");
4779 }
4780
4781 if (C.kind == CXCursor_VisibilityAttr) {
4782 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4783 switch (AA->getVisibility()) {
4784 case VisibilityAttr::VisibilityType::Default:
4785 return cxstring::createRef("default");
4786 case VisibilityAttr::VisibilityType::Hidden:
4787 return cxstring::createRef("hidden");
4788 case VisibilityAttr::VisibilityType::Protected:
4789 return cxstring::createRef("protected");
4790 }
4791 llvm_unreachable("unknown visibility type");
4792 }
4793
4794 return cxstring::createEmpty();
4795 }
4796
4797 CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
4798 unsigned options) {
4799 if (clang_Cursor_isNull(C))
4800 return clang_getNullRange();
4801
4802 ASTContext &Ctx = getCursorContext(C);
4803
4804 if (clang_isStatement(C.kind)) {
4805 const Stmt *S = getCursorStmt(C);
4806 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
4807 if (pieceIndex > 0)
4808 return clang_getNullRange();
4809 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4810 }
4811
4812 return clang_getNullRange();
4813 }
4814
4815 if (C.kind == CXCursor_ObjCMessageExpr) {
4816 if (const ObjCMessageExpr *ME =
4817 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4818 if (pieceIndex >= ME->getNumSelectorLocs())
4819 return clang_getNullRange();
4820 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4821 }
4822 }
4823
4824 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4825 C.kind == CXCursor_ObjCClassMethodDecl) {
4826 if (const ObjCMethodDecl *MD =
4827 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4828 if (pieceIndex >= MD->getNumSelectorLocs())
4829 return clang_getNullRange();
4830 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4831 }
4832 }
4833
4834 if (C.kind == CXCursor_ObjCCategoryDecl ||
4835 C.kind == CXCursor_ObjCCategoryImplDecl) {
4836 if (pieceIndex > 0)
4837 return clang_getNullRange();
4838 if (const ObjCCategoryDecl *CD =
4839 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4840 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
4841 if (const ObjCCategoryImplDecl *CID =
4842 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4843 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4844 }
4845
4846 if (C.kind == CXCursor_ModuleImportDecl) {
4847 if (pieceIndex > 0)
4848 return clang_getNullRange();
4849 if (const ImportDecl *ImportD =
4850 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
4851 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4852 if (!Locs.empty())
4853 return cxloc::translateSourceRange(
4854 Ctx, SourceRange(Locs.front(), Locs.back()));
4855 }
4856 return clang_getNullRange();
4857 }
4858
4859 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4860 C.kind == CXCursor_ConversionFunction ||
4861 C.kind == CXCursor_FunctionDecl) {
4862 if (pieceIndex > 0)
4863 return clang_getNullRange();
4864 if (const FunctionDecl *FD =
4865 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4866 DeclarationNameInfo FunctionName = FD->getNameInfo();
4867 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4868 }
4869 return clang_getNullRange();
4870 }
4871
4872 // FIXME: A CXCursor_InclusionDirective should give the location of the
4873 // filename, but we don't keep track of this.
4874
4875 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4876 // but we don't keep track of this.
4877
4878 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4879 // but we don't keep track of this.
4880
4881 // Default handling, give the location of the cursor.
4882
4883 if (pieceIndex > 0)
4884 return clang_getNullRange();
4885
4886 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4887 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4888 return cxloc::translateSourceRange(Ctx, Loc);
4889 }
4890
4891 CXString clang_Cursor_getMangling(CXCursor C) {
4892 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4893 return cxstring::createEmpty();
4894
4895 // Mangling only works for functions and variables.
4896 const Decl *D = getCursorDecl(C);
4897 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4898 return cxstring::createEmpty();
4899
4900 ASTContext &Ctx = D->getASTContext();
4901 ASTNameGenerator ASTNameGen(Ctx);
4902 return cxstring::createDup(ASTNameGen.getName(D));
4903 }
4904
4905 CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4906 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4907 return nullptr;
4908
4909 const Decl *D = getCursorDecl(C);
4910 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4911 return nullptr;
4912
4913 ASTContext &Ctx = D->getASTContext();
4914 ASTNameGenerator ASTNameGen(Ctx);
4915 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
4916 return cxstring::createSet(Manglings);
4917 }
4918
4919 CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
4920 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4921 return nullptr;
4922
4923 const Decl *D = getCursorDecl(C);
4924 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
4925 return nullptr;
4926
4927 ASTContext &Ctx = D->getASTContext();
4928 ASTNameGenerator ASTNameGen(Ctx);
4929 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
4930 return cxstring::createSet(Manglings);
4931 }
4932
4933 CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
4934 if (clang_Cursor_isNull(C))
4935 return 0;
4936 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
4937 }
4938
4939 void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
4940 if (Policy)
4941 delete static_cast<PrintingPolicy *>(Policy);
4942 }
4943
4944 unsigned
4945 clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
4946 enum CXPrintingPolicyProperty Property) {
4947 if (!Policy)
4948 return 0;
4949
4950 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4951 switch (Property) {
4952 case CXPrintingPolicy_Indentation:
4953 return P->Indentation;
4954 case CXPrintingPolicy_SuppressSpecifiers:
4955 return P->SuppressSpecifiers;
4956 case CXPrintingPolicy_SuppressTagKeyword:
4957 return P->SuppressTagKeyword;
4958 case CXPrintingPolicy_IncludeTagDefinition:
4959 return P->IncludeTagDefinition;
4960 case CXPrintingPolicy_SuppressScope:
4961 return P->SuppressScope;
4962 case CXPrintingPolicy_SuppressUnwrittenScope:
4963 return P->SuppressUnwrittenScope;
4964 case CXPrintingPolicy_SuppressInitializers:
4965 return P->SuppressInitializers;
4966 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4967 return P->ConstantArraySizeAsWritten;
4968 case CXPrintingPolicy_AnonymousTagLocations:
4969 return P->AnonymousTagLocations;
4970 case CXPrintingPolicy_SuppressStrongLifetime:
4971 return P->SuppressStrongLifetime;
4972 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4973 return P->SuppressLifetimeQualifiers;
4974 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4975 return P->SuppressTemplateArgsInCXXConstructors;
4976 case CXPrintingPolicy_Bool:
4977 return P->Bool;
4978 case CXPrintingPolicy_Restrict:
4979 return P->Restrict;
4980 case CXPrintingPolicy_Alignof:
4981 return P->Alignof;
4982 case CXPrintingPolicy_UnderscoreAlignof:
4983 return P->UnderscoreAlignof;
4984 case CXPrintingPolicy_UseVoidForZeroParams:
4985 return P->UseVoidForZeroParams;
4986 case CXPrintingPolicy_TerseOutput:
4987 return P->TerseOutput;
4988 case CXPrintingPolicy_PolishForDeclaration:
4989 return P->PolishForDeclaration;
4990 case CXPrintingPolicy_Half:
4991 return P->Half;
4992 case CXPrintingPolicy_MSWChar:
4993 return P->MSWChar;
4994 case CXPrintingPolicy_IncludeNewlines:
4995 return P->IncludeNewlines;
4996 case CXPrintingPolicy_MSVCFormatting:
4997 return P->MSVCFormatting;
4998 case CXPrintingPolicy_ConstantsAsWritten:
4999 return P->ConstantsAsWritten;
5000 case CXPrintingPolicy_SuppressImplicitBase:
5001 return P->SuppressImplicitBase;
5002 case CXPrintingPolicy_FullyQualifiedName:
5003 return P->FullyQualifiedName;
5004 }
5005
5006 assert(false && "Invalid CXPrintingPolicyProperty");
5007 return 0;
5008 }
5009
5010 void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
5011 enum CXPrintingPolicyProperty Property,
5012 unsigned Value) {
5013 if (!Policy)
5014 return;
5015
5016 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
5017 switch (Property) {
5018 case CXPrintingPolicy_Indentation:
5019 P->Indentation = Value;
5020 return;
5021 case CXPrintingPolicy_SuppressSpecifiers:
5022 P->SuppressSpecifiers = Value;
5023 return;
5024 case CXPrintingPolicy_SuppressTagKeyword:
5025 P->SuppressTagKeyword = Value;
5026 return;
5027 case CXPrintingPolicy_IncludeTagDefinition:
5028 P->IncludeTagDefinition = Value;
5029 return;
5030 case CXPrintingPolicy_SuppressScope:
5031 P->SuppressScope = Value;
5032 return;
5033 case CXPrintingPolicy_SuppressUnwrittenScope:
5034 P->SuppressUnwrittenScope = Value;
5035 return;
5036 case CXPrintingPolicy_SuppressInitializers:
5037 P->SuppressInitializers = Value;
5038 return;
5039 case CXPrintingPolicy_ConstantArraySizeAsWritten:
5040 P->ConstantArraySizeAsWritten = Value;
5041 return;
5042 case CXPrintingPolicy_AnonymousTagLocations:
5043 P->AnonymousTagLocations = Value;
5044 return;
5045 case CXPrintingPolicy_SuppressStrongLifetime:
5046 P->SuppressStrongLifetime = Value;
5047 return;
5048 case CXPrintingPolicy_SuppressLifetimeQualifiers:
5049 P->SuppressLifetimeQualifiers = Value;
5050 return;
5051 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
5052 P->SuppressTemplateArgsInCXXConstructors = Value;
5053 return;
5054 case CXPrintingPolicy_Bool:
5055 P->Bool = Value;
5056 return;
5057 case CXPrintingPolicy_Restrict:
5058 P->Restrict = Value;
5059 return;
5060 case CXPrintingPolicy_Alignof:
5061 P->Alignof = Value;
5062 return;
5063 case CXPrintingPolicy_UnderscoreAlignof:
5064 P->UnderscoreAlignof = Value;
5065 return;
5066 case CXPrintingPolicy_UseVoidForZeroParams:
5067 P->UseVoidForZeroParams = Value;
5068 return;
5069 case CXPrintingPolicy_TerseOutput:
5070 P->TerseOutput = Value;
5071 return;
5072 case CXPrintingPolicy_PolishForDeclaration:
5073 P->PolishForDeclaration = Value;
5074 return;
5075 case CXPrintingPolicy_Half:
5076 P->Half = Value;
5077 return;
5078 case CXPrintingPolicy_MSWChar:
5079 P->MSWChar = Value;
5080 return;
5081 case CXPrintingPolicy_IncludeNewlines:
5082 P->IncludeNewlines = Value;
5083 return;
5084 case CXPrintingPolicy_MSVCFormatting:
5085 P->MSVCFormatting = Value;
5086 return;
5087 case CXPrintingPolicy_ConstantsAsWritten:
5088 P->ConstantsAsWritten = Value;
5089 return;
5090 case CXPrintingPolicy_SuppressImplicitBase:
5091 P->SuppressImplicitBase = Value;
5092 return;
5093 case CXPrintingPolicy_FullyQualifiedName:
5094 P->FullyQualifiedName = Value;
5095 return;
5096 }
5097
5098 assert(false && "Invalid CXPrintingPolicyProperty");
5099 }
5100
5101 CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
5102 if (clang_Cursor_isNull(C))
5103 return cxstring::createEmpty();
5104
5105 if (clang_isDeclaration(C.kind)) {
5106 const Decl *D = getCursorDecl(C);
5107 if (!D)
5108 return cxstring::createEmpty();
5109
5110 SmallString<128> Str;
5111 llvm::raw_svector_ostream OS(Str);
5112 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5113 D->print(OS, UserPolicy ? *UserPolicy
5114 : getCursorContext(C).getPrintingPolicy());
5115
5116 return cxstring::createDup(OS.str());
5117 }
5118
5119 return cxstring::createEmpty();
5120 }
5121
5122 CXString clang_getCursorDisplayName(CXCursor C) {
5123 if (!clang_isDeclaration(C.kind))
5124 return clang_getCursorSpelling(C);
5125
5126 const Decl *D = getCursorDecl(C);
5127 if (!D)
5128 return cxstring::createEmpty();
5129
5130 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
5131 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
5132 D = FunTmpl->getTemplatedDecl();
5133
5134 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
5135 SmallString<64> Str;
5136 llvm::raw_svector_ostream OS(Str);
5137 OS << *Function;
5138 if (Function->getPrimaryTemplate())
5139 OS << "<>";
5140 OS << "(";
5141 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5142 if (I)
5143 OS << ", ";
5144 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5145 }
5146
5147 if (Function->isVariadic()) {
5148 if (Function->getNumParams())
5149 OS << ", ";
5150 OS << "...";
5151 }
5152 OS << ")";
5153 return cxstring::createDup(OS.str());
5154 }
5155
5156 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
5157 SmallString<64> Str;
5158 llvm::raw_svector_ostream OS(Str);
5159 OS << *ClassTemplate;
5160 OS << "<";
5161 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5162 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5163 if (I)
5164 OS << ", ";
5165
5166 NamedDecl *Param = Params->getParam(I);
5167 if (Param->getIdentifier()) {
5168 OS << Param->getIdentifier()->getName();
5169 continue;
5170 }
5171
5172 // There is no parameter name, which makes this tricky. Try to come up
5173 // with something useful that isn't too long.
5174 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
5175 if (const auto *TC = TTP->getTypeConstraint()) {
5176 TC->getConceptNameInfo().printName(OS, Policy);
5177 if (TC->hasExplicitTemplateArgs())
5178 OS << "<...>";
5179 } else
5180 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5181 else if (NonTypeTemplateParmDecl *NTTP =
5182 dyn_cast<NonTypeTemplateParmDecl>(Param))
5183 OS << NTTP->getType().getAsString(Policy);
5184 else
5185 OS << "template<...> class";
5186 }
5187
5188 OS << ">";
5189 return cxstring::createDup(OS.str());
5190 }
5191
5192 if (const ClassTemplateSpecializationDecl *ClassSpec =
5193 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
5194 // If the type was explicitly written, use that.
5195 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
5196 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
5197
5198 SmallString<128> Str;
5199 llvm::raw_svector_ostream OS(Str);
5200 OS << *ClassSpec;
5201 printTemplateArgumentList(
5202 OS, ClassSpec->getTemplateArgs().asArray(), Policy,
5203 ClassSpec->getSpecializedTemplate()->getTemplateParameters());
5204 return cxstring::createDup(OS.str());
5205 }
5206
5207 return clang_getCursorSpelling(C);
5208 }
5209
5210 CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5211 switch (Kind) {
5212 case CXCursor_FunctionDecl:
5213 return cxstring::createRef("FunctionDecl");
5214 case CXCursor_TypedefDecl:
5215 return cxstring::createRef("TypedefDecl");
5216 case CXCursor_EnumDecl:
5217 return cxstring::createRef("EnumDecl");
5218 case CXCursor_EnumConstantDecl:
5219 return cxstring::createRef("EnumConstantDecl");
5220 case CXCursor_StructDecl:
5221 return cxstring::createRef("StructDecl");
5222 case CXCursor_UnionDecl:
5223 return cxstring::createRef("UnionDecl");
5224 case CXCursor_ClassDecl:
5225 return cxstring::createRef("ClassDecl");
5226 case CXCursor_FieldDecl:
5227 return cxstring::createRef("FieldDecl");
5228 case CXCursor_VarDecl:
5229 return cxstring::createRef("VarDecl");
5230 case CXCursor_ParmDecl:
5231 return cxstring::createRef("ParmDecl");
5232 case CXCursor_ObjCInterfaceDecl:
5233 return cxstring::createRef("ObjCInterfaceDecl");
5234 case CXCursor_ObjCCategoryDecl:
5235 return cxstring::createRef("ObjCCategoryDecl");
5236 case CXCursor_ObjCProtocolDecl:
5237 return cxstring::createRef("ObjCProtocolDecl");
5238 case CXCursor_ObjCPropertyDecl:
5239 return cxstring::createRef("ObjCPropertyDecl");
5240 case CXCursor_ObjCIvarDecl:
5241 return cxstring::createRef("ObjCIvarDecl");
5242 case CXCursor_ObjCInstanceMethodDecl:
5243 return cxstring::createRef("ObjCInstanceMethodDecl");
5244 case CXCursor_ObjCClassMethodDecl:
5245 return cxstring::createRef("ObjCClassMethodDecl");
5246 case CXCursor_ObjCImplementationDecl:
5247 return cxstring::createRef("ObjCImplementationDecl");
5248 case CXCursor_ObjCCategoryImplDecl:
5249 return cxstring::createRef("ObjCCategoryImplDecl");
5250 case CXCursor_CXXMethod:
5251 return cxstring::createRef("CXXMethod");
5252 case CXCursor_UnexposedDecl:
5253 return cxstring::createRef("UnexposedDecl");
5254 case CXCursor_ObjCSuperClassRef:
5255 return cxstring::createRef("ObjCSuperClassRef");
5256 case CXCursor_ObjCProtocolRef:
5257 return cxstring::createRef("ObjCProtocolRef");
5258 case CXCursor_ObjCClassRef:
5259 return cxstring::createRef("ObjCClassRef");
5260 case CXCursor_TypeRef:
5261 return cxstring::createRef("TypeRef");
5262 case CXCursor_TemplateRef:
5263 return cxstring::createRef("TemplateRef");
5264 case CXCursor_NamespaceRef:
5265 return cxstring::createRef("NamespaceRef");
5266 case CXCursor_MemberRef:
5267 return cxstring::createRef("MemberRef");
5268 case CXCursor_LabelRef:
5269 return cxstring::createRef("LabelRef");
5270 case CXCursor_OverloadedDeclRef:
5271 return cxstring::createRef("OverloadedDeclRef");
5272 case CXCursor_VariableRef:
5273 return cxstring::createRef("VariableRef");
5274 case CXCursor_IntegerLiteral:
5275 return cxstring::createRef("IntegerLiteral");
5276 case CXCursor_FixedPointLiteral:
5277 return cxstring::createRef("FixedPointLiteral");
5278 case CXCursor_FloatingLiteral:
5279 return cxstring::createRef("FloatingLiteral");
5280 case CXCursor_ImaginaryLiteral:
5281 return cxstring::createRef("ImaginaryLiteral");
5282 case CXCursor_StringLiteral:
5283 return cxstring::createRef("StringLiteral");
5284 case CXCursor_CharacterLiteral:
5285 return cxstring::createRef("CharacterLiteral");
5286 case CXCursor_ParenExpr:
5287 return cxstring::createRef("ParenExpr");
5288 case CXCursor_UnaryOperator:
5289 return cxstring::createRef("UnaryOperator");
5290 case CXCursor_ArraySubscriptExpr:
5291 return cxstring::createRef("ArraySubscriptExpr");
5292 case CXCursor_OMPArraySectionExpr:
5293 return cxstring::createRef("OMPArraySectionExpr");
5294 case CXCursor_OMPArrayShapingExpr:
5295 return cxstring::createRef("OMPArrayShapingExpr");
5296 case CXCursor_OMPIteratorExpr:
5297 return cxstring::createRef("OMPIteratorExpr");
5298 case CXCursor_BinaryOperator:
5299 return cxstring::createRef("BinaryOperator");
5300 case CXCursor_CompoundAssignOperator:
5301 return cxstring::createRef("CompoundAssignOperator");
5302 case CXCursor_ConditionalOperator:
5303 return cxstring::createRef("ConditionalOperator");
5304 case CXCursor_CStyleCastExpr:
5305 return cxstring::createRef("CStyleCastExpr");
5306 case CXCursor_CompoundLiteralExpr:
5307 return cxstring::createRef("CompoundLiteralExpr");
5308 case CXCursor_InitListExpr:
5309 return cxstring::createRef("InitListExpr");
5310 case CXCursor_AddrLabelExpr:
5311 return cxstring::createRef("AddrLabelExpr");
5312 case CXCursor_StmtExpr:
5313 return cxstring::createRef("StmtExpr");
5314 case CXCursor_GenericSelectionExpr:
5315 return cxstring::createRef("GenericSelectionExpr");
5316 case CXCursor_GNUNullExpr:
5317 return cxstring::createRef("GNUNullExpr");
5318 case CXCursor_CXXStaticCastExpr:
5319 return cxstring::createRef("CXXStaticCastExpr");
5320 case CXCursor_CXXDynamicCastExpr:
5321 return cxstring::createRef("CXXDynamicCastExpr");
5322 case CXCursor_CXXReinterpretCastExpr:
5323 return cxstring::createRef("CXXReinterpretCastExpr");
5324 case CXCursor_CXXConstCastExpr:
5325 return cxstring::createRef("CXXConstCastExpr");
5326 case CXCursor_CXXFunctionalCastExpr:
5327 return cxstring::createRef("CXXFunctionalCastExpr");
5328 case CXCursor_CXXAddrspaceCastExpr:
5329 return cxstring::createRef("CXXAddrspaceCastExpr");
5330 case CXCursor_CXXTypeidExpr:
5331 return cxstring::createRef("CXXTypeidExpr");
5332 case CXCursor_CXXBoolLiteralExpr:
5333 return cxstring::createRef("CXXBoolLiteralExpr");
5334 case CXCursor_CXXNullPtrLiteralExpr:
5335 return cxstring::createRef("CXXNullPtrLiteralExpr");
5336 case CXCursor_CXXThisExpr:
5337 return cxstring::createRef("CXXThisExpr");
5338 case CXCursor_CXXThrowExpr:
5339 return cxstring::createRef("CXXThrowExpr");
5340 case CXCursor_CXXNewExpr:
5341 return cxstring::createRef("CXXNewExpr");
5342 case CXCursor_CXXDeleteExpr:
5343 return cxstring::createRef("CXXDeleteExpr");
5344 case CXCursor_UnaryExpr:
5345 return cxstring::createRef("UnaryExpr");
5346 case CXCursor_ObjCStringLiteral:
5347 return cxstring::createRef("ObjCStringLiteral");
5348 case CXCursor_ObjCBoolLiteralExpr:
5349 return cxstring::createRef("ObjCBoolLiteralExpr");
5350 case CXCursor_ObjCAvailabilityCheckExpr:
5351 return cxstring::createRef("ObjCAvailabilityCheckExpr");
5352 case CXCursor_ObjCSelfExpr:
5353 return cxstring::createRef("ObjCSelfExpr");
5354 case CXCursor_ObjCEncodeExpr:
5355 return cxstring::createRef("ObjCEncodeExpr");
5356 case CXCursor_ObjCSelectorExpr:
5357 return cxstring::createRef("ObjCSelectorExpr");
5358 case CXCursor_ObjCProtocolExpr:
5359 return cxstring::createRef("ObjCProtocolExpr");
5360 case CXCursor_ObjCBridgedCastExpr:
5361 return cxstring::createRef("ObjCBridgedCastExpr");
5362 case CXCursor_BlockExpr:
5363 return cxstring::createRef("BlockExpr");
5364 case CXCursor_PackExpansionExpr:
5365 return cxstring::createRef("PackExpansionExpr");
5366 case CXCursor_SizeOfPackExpr:
5367 return cxstring::createRef("SizeOfPackExpr");
5368 case CXCursor_LambdaExpr:
5369 return cxstring::createRef("LambdaExpr");
5370 case CXCursor_UnexposedExpr:
5371 return cxstring::createRef("UnexposedExpr");
5372 case CXCursor_DeclRefExpr:
5373 return cxstring::createRef("DeclRefExpr");
5374 case CXCursor_MemberRefExpr:
5375 return cxstring::createRef("MemberRefExpr");
5376 case CXCursor_CallExpr:
5377 return cxstring::createRef("CallExpr");
5378 case CXCursor_ObjCMessageExpr:
5379 return cxstring::createRef("ObjCMessageExpr");
5380 case CXCursor_BuiltinBitCastExpr:
5381 return cxstring::createRef("BuiltinBitCastExpr");
5382 case CXCursor_UnexposedStmt:
5383 return cxstring::createRef("UnexposedStmt");
5384 case CXCursor_DeclStmt:
5385 return cxstring::createRef("DeclStmt");
5386 case CXCursor_LabelStmt:
5387 return cxstring::createRef("LabelStmt");
5388 case CXCursor_CompoundStmt:
5389 return cxstring::createRef("CompoundStmt");
5390 case CXCursor_CaseStmt:
5391 return cxstring::createRef("CaseStmt");
5392 case CXCursor_DefaultStmt:
5393 return cxstring::createRef("DefaultStmt");
5394 case CXCursor_IfStmt:
5395 return cxstring::createRef("IfStmt");
5396 case CXCursor_SwitchStmt:
5397 return cxstring::createRef("SwitchStmt");
5398 case CXCursor_WhileStmt:
5399 return cxstring::createRef("WhileStmt");
5400 case CXCursor_DoStmt:
5401 return cxstring::createRef("DoStmt");
5402 case CXCursor_ForStmt:
5403 return cxstring::createRef("ForStmt");
5404 case CXCursor_GotoStmt:
5405 return cxstring::createRef("GotoStmt");
5406 case CXCursor_IndirectGotoStmt:
5407 return cxstring::createRef("IndirectGotoStmt");
5408 case CXCursor_ContinueStmt:
5409 return cxstring::createRef("ContinueStmt");
5410 case CXCursor_BreakStmt:
5411 return cxstring::createRef("BreakStmt");
5412 case CXCursor_ReturnStmt:
5413 return cxstring::createRef("ReturnStmt");
5414 case CXCursor_GCCAsmStmt:
5415 return cxstring::createRef("GCCAsmStmt");
5416 case CXCursor_MSAsmStmt:
5417 return cxstring::createRef("MSAsmStmt");
5418 case CXCursor_ObjCAtTryStmt:
5419 return cxstring::createRef("ObjCAtTryStmt");
5420 case CXCursor_ObjCAtCatchStmt:
5421 return cxstring::createRef("ObjCAtCatchStmt");
5422 case CXCursor_ObjCAtFinallyStmt:
5423 return cxstring::createRef("ObjCAtFinallyStmt");
5424 case CXCursor_ObjCAtThrowStmt:
5425 return cxstring::createRef("ObjCAtThrowStmt");
5426 case CXCursor_ObjCAtSynchronizedStmt:
5427 return cxstring::createRef("ObjCAtSynchronizedStmt");
5428 case CXCursor_ObjCAutoreleasePoolStmt:
5429 return cxstring::createRef("ObjCAutoreleasePoolStmt");
5430 case CXCursor_ObjCForCollectionStmt:
5431 return cxstring::createRef("ObjCForCollectionStmt");
5432 case CXCursor_CXXCatchStmt:
5433 return cxstring::createRef("CXXCatchStmt");
5434 case CXCursor_CXXTryStmt:
5435 return cxstring::createRef("CXXTryStmt");
5436 case CXCursor_CXXForRangeStmt:
5437 return cxstring::createRef("CXXForRangeStmt");
5438 case CXCursor_SEHTryStmt:
5439 return cxstring::createRef("SEHTryStmt");
5440 case CXCursor_SEHExceptStmt:
5441 return cxstring::createRef("SEHExceptStmt");
5442 case CXCursor_SEHFinallyStmt:
5443 return cxstring::createRef("SEHFinallyStmt");
5444 case CXCursor_SEHLeaveStmt:
5445 return cxstring::createRef("SEHLeaveStmt");
5446 case CXCursor_NullStmt:
5447 return cxstring::createRef("NullStmt");
5448 case CXCursor_InvalidFile:
5449 return cxstring::createRef("InvalidFile");
5450 case CXCursor_InvalidCode:
5451 return cxstring::createRef("InvalidCode");
5452 case CXCursor_NoDeclFound:
5453 return cxstring::createRef("NoDeclFound");
5454 case CXCursor_NotImplemented:
5455 return cxstring::createRef("NotImplemented");
5456 case CXCursor_TranslationUnit:
5457 return cxstring::createRef("TranslationUnit");
5458 case CXCursor_UnexposedAttr:
5459 return cxstring::createRef("UnexposedAttr");
5460 case CXCursor_IBActionAttr:
5461 return cxstring::createRef("attribute(ibaction)");
5462 case CXCursor_IBOutletAttr:
5463 return cxstring::createRef("attribute(iboutlet)");
5464 case CXCursor_IBOutletCollectionAttr:
5465 return cxstring::createRef("attribute(iboutletcollection)");
5466 case CXCursor_CXXFinalAttr:
5467 return cxstring::createRef("attribute(final)");
5468 case CXCursor_CXXOverrideAttr:
5469 return cxstring::createRef("attribute(override)");
5470 case CXCursor_AnnotateAttr:
5471 return cxstring::createRef("attribute(annotate)");
5472 case CXCursor_AsmLabelAttr:
5473 return cxstring::createRef("asm label");
5474 case CXCursor_PackedAttr:
5475 return cxstring::createRef("attribute(packed)");
5476 case CXCursor_PureAttr:
5477 return cxstring::createRef("attribute(pure)");
5478 case CXCursor_ConstAttr:
5479 return cxstring::createRef("attribute(const)");
5480 case CXCursor_NoDuplicateAttr:
5481 return cxstring::createRef("attribute(noduplicate)");
5482 case CXCursor_CUDAConstantAttr:
5483 return cxstring::createRef("attribute(constant)");
5484 case CXCursor_CUDADeviceAttr:
5485 return cxstring::createRef("attribute(device)");
5486 case CXCursor_CUDAGlobalAttr:
5487 return cxstring::createRef("attribute(global)");
5488 case CXCursor_CUDAHostAttr:
5489 return cxstring::createRef("attribute(host)");
5490 case CXCursor_CUDASharedAttr:
5491 return cxstring::createRef("attribute(shared)");
5492 case CXCursor_VisibilityAttr:
5493 return cxstring::createRef("attribute(visibility)");
5494 case CXCursor_DLLExport:
5495 return cxstring::createRef("attribute(dllexport)");
5496 case CXCursor_DLLImport:
5497 return cxstring::createRef("attribute(dllimport)");
5498 case CXCursor_NSReturnsRetained:
5499 return cxstring::createRef("attribute(ns_returns_retained)");
5500 case CXCursor_NSReturnsNotRetained:
5501 return cxstring::createRef("attribute(ns_returns_not_retained)");
5502 case CXCursor_NSReturnsAutoreleased:
5503 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5504 case CXCursor_NSConsumesSelf:
5505 return cxstring::createRef("attribute(ns_consumes_self)");
5506 case CXCursor_NSConsumed:
5507 return cxstring::createRef("attribute(ns_consumed)");
5508 case CXCursor_ObjCException:
5509 return cxstring::createRef("attribute(objc_exception)");
5510 case CXCursor_ObjCNSObject:
5511 return cxstring::createRef("attribute(NSObject)");
5512 case CXCursor_ObjCIndependentClass:
5513 return cxstring::createRef("attribute(objc_independent_class)");
5514 case CXCursor_ObjCPreciseLifetime:
5515 return cxstring::createRef("attribute(objc_precise_lifetime)");
5516 case CXCursor_ObjCReturnsInnerPointer:
5517 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5518 case CXCursor_ObjCRequiresSuper:
5519 return cxstring::createRef("attribute(objc_requires_super)");
5520 case CXCursor_ObjCRootClass:
5521 return cxstring::createRef("attribute(objc_root_class)");
5522 case CXCursor_ObjCSubclassingRestricted:
5523 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5524 case CXCursor_ObjCExplicitProtocolImpl:
5525 return cxstring::createRef(
5526 "attribute(objc_protocol_requires_explicit_implementation)");
5527 case CXCursor_ObjCDesignatedInitializer:
5528 return cxstring::createRef("attribute(objc_designated_initializer)");
5529 case CXCursor_ObjCRuntimeVisible:
5530 return cxstring::createRef("attribute(objc_runtime_visible)");
5531 case CXCursor_ObjCBoxable:
5532 return cxstring::createRef("attribute(objc_boxable)");
5533 case CXCursor_FlagEnum:
5534 return cxstring::createRef("attribute(flag_enum)");
5535 case CXCursor_PreprocessingDirective:
5536 return cxstring::createRef("preprocessing directive");
5537 case CXCursor_MacroDefinition:
5538 return cxstring::createRef("macro definition");
5539 case CXCursor_MacroExpansion:
5540 return cxstring::createRef("macro expansion");
5541 case CXCursor_InclusionDirective:
5542 return cxstring::createRef("inclusion directive");
5543 case CXCursor_Namespace:
5544 return cxstring::createRef("Namespace");
5545 case CXCursor_LinkageSpec:
5546 return cxstring::createRef("LinkageSpec");
5547 case CXCursor_CXXBaseSpecifier:
5548 return cxstring::createRef("C++ base class specifier");
5549 case CXCursor_Constructor:
5550 return cxstring::createRef("CXXConstructor");
5551 case CXCursor_Destructor:
5552 return cxstring::createRef("CXXDestructor");
5553 case CXCursor_ConversionFunction:
5554 return cxstring::createRef("CXXConversion");
5555 case CXCursor_TemplateTypeParameter:
5556 return cxstring::createRef("TemplateTypeParameter");
5557 case CXCursor_NonTypeTemplateParameter:
5558 return cxstring::createRef("NonTypeTemplateParameter");
5559 case CXCursor_TemplateTemplateParameter:
5560 return cxstring::createRef("TemplateTemplateParameter");
5561 case CXCursor_FunctionTemplate:
5562 return cxstring::createRef("FunctionTemplate");
5563 case CXCursor_ClassTemplate:
5564 return cxstring::createRef("ClassTemplate");
5565 case CXCursor_ClassTemplatePartialSpecialization:
5566 return cxstring::createRef("ClassTemplatePartialSpecialization");
5567 case CXCursor_NamespaceAlias:
5568 return cxstring::createRef("NamespaceAlias");
5569 case CXCursor_UsingDirective:
5570 return cxstring::createRef("UsingDirective");
5571 case CXCursor_UsingDeclaration:
5572 return cxstring::createRef("UsingDeclaration");
5573 case CXCursor_TypeAliasDecl:
5574 return cxstring::createRef("TypeAliasDecl");
5575 case CXCursor_ObjCSynthesizeDecl:
5576 return cxstring::createRef("ObjCSynthesizeDecl");
5577 case CXCursor_ObjCDynamicDecl:
5578 return cxstring::createRef("ObjCDynamicDecl");
5579 case CXCursor_CXXAccessSpecifier:
5580 return cxstring::createRef("CXXAccessSpecifier");
5581 case CXCursor_ModuleImportDecl:
5582 return cxstring::createRef("ModuleImport");
5583 case CXCursor_OMPCanonicalLoop:
5584 return cxstring::createRef("OMPCanonicalLoop");
5585 case CXCursor_OMPParallelDirective:
5586 return cxstring::createRef("OMPParallelDirective");
5587 case CXCursor_OMPSimdDirective:
5588 return cxstring::createRef("OMPSimdDirective");
5589 case CXCursor_OMPTileDirective:
5590 return cxstring::createRef("OMPTileDirective");
5591 case CXCursor_OMPUnrollDirective:
5592 return cxstring::createRef("OMPUnrollDirective");
5593 case CXCursor_OMPForDirective:
5594 return cxstring::createRef("OMPForDirective");
5595 case CXCursor_OMPForSimdDirective:
5596 return cxstring::createRef("OMPForSimdDirective");
5597 case CXCursor_OMPSectionsDirective:
5598 return cxstring::createRef("OMPSectionsDirective");
5599 case CXCursor_OMPSectionDirective:
5600 return cxstring::createRef("OMPSectionDirective");
5601 case CXCursor_OMPSingleDirective:
5602 return cxstring::createRef("OMPSingleDirective");
5603 case CXCursor_OMPMasterDirective:
5604 return cxstring::createRef("OMPMasterDirective");
5605 case CXCursor_OMPCriticalDirective:
5606 return cxstring::createRef("OMPCriticalDirective");
5607 case CXCursor_OMPParallelForDirective:
5608 return cxstring::createRef("OMPParallelForDirective");
5609 case CXCursor_OMPParallelForSimdDirective:
5610 return cxstring::createRef("OMPParallelForSimdDirective");
5611 case CXCursor_OMPParallelMasterDirective:
5612 return cxstring::createRef("OMPParallelMasterDirective");
5613 case CXCursor_OMPParallelSectionsDirective:
5614 return cxstring::createRef("OMPParallelSectionsDirective");
5615 case CXCursor_OMPTaskDirective:
5616 return cxstring::createRef("OMPTaskDirective");
5617 case CXCursor_OMPTaskyieldDirective:
5618 return cxstring::createRef("OMPTaskyieldDirective");
5619 case CXCursor_OMPBarrierDirective:
5620 return cxstring::createRef("OMPBarrierDirective");
5621 case CXCursor_OMPTaskwaitDirective:
5622 return cxstring::createRef("OMPTaskwaitDirective");
5623 case CXCursor_OMPTaskgroupDirective:
5624 return cxstring::createRef("OMPTaskgroupDirective");
5625 case CXCursor_OMPFlushDirective:
5626 return cxstring::createRef("OMPFlushDirective");
5627 case CXCursor_OMPDepobjDirective:
5628 return cxstring::createRef("OMPDepobjDirective");
5629 case CXCursor_OMPScanDirective:
5630 return cxstring::createRef("OMPScanDirective");
5631 case CXCursor_OMPOrderedDirective:
5632 return cxstring::createRef("OMPOrderedDirective");
5633 case CXCursor_OMPAtomicDirective:
5634 return cxstring::createRef("OMPAtomicDirective");
5635 case CXCursor_OMPTargetDirective:
5636 return cxstring::createRef("OMPTargetDirective");
5637 case CXCursor_OMPTargetDataDirective:
5638 return cxstring::createRef("OMPTargetDataDirective");
5639 case CXCursor_OMPTargetEnterDataDirective:
5640 return cxstring::createRef("OMPTargetEnterDataDirective");
5641 case CXCursor_OMPTargetExitDataDirective:
5642 return cxstring::createRef("OMPTargetExitDataDirective");
5643 case CXCursor_OMPTargetParallelDirective:
5644 return cxstring::createRef("OMPTargetParallelDirective");
5645 case CXCursor_OMPTargetParallelForDirective:
5646 return cxstring::createRef("OMPTargetParallelForDirective");
5647 case CXCursor_OMPTargetUpdateDirective:
5648 return cxstring::createRef("OMPTargetUpdateDirective");
5649 case CXCursor_OMPTeamsDirective:
5650 return cxstring::createRef("OMPTeamsDirective");
5651 case CXCursor_OMPCancellationPointDirective:
5652 return cxstring::createRef("OMPCancellationPointDirective");
5653 case CXCursor_OMPCancelDirective:
5654 return cxstring::createRef("OMPCancelDirective");
5655 case CXCursor_OMPTaskLoopDirective:
5656 return cxstring::createRef("OMPTaskLoopDirective");
5657 case CXCursor_OMPTaskLoopSimdDirective:
5658 return cxstring::createRef("OMPTaskLoopSimdDirective");
5659 case CXCursor_OMPMasterTaskLoopDirective:
5660 return cxstring::createRef("OMPMasterTaskLoopDirective");
5661 case CXCursor_OMPMasterTaskLoopSimdDirective:
5662 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
5663 case CXCursor_OMPParallelMasterTaskLoopDirective:
5664 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
5665 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5666 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
5667 case CXCursor_OMPDistributeDirective:
5668 return cxstring::createRef("OMPDistributeDirective");
5669 case CXCursor_OMPDistributeParallelForDirective:
5670 return cxstring::createRef("OMPDistributeParallelForDirective");
5671 case CXCursor_OMPDistributeParallelForSimdDirective:
5672 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
5673 case CXCursor_OMPDistributeSimdDirective:
5674 return cxstring::createRef("OMPDistributeSimdDirective");
5675 case CXCursor_OMPTargetParallelForSimdDirective:
5676 return cxstring::createRef("OMPTargetParallelForSimdDirective");
5677 case CXCursor_OMPTargetSimdDirective:
5678 return cxstring::createRef("OMPTargetSimdDirective");
5679 case CXCursor_OMPTeamsDistributeDirective:
5680 return cxstring::createRef("OMPTeamsDistributeDirective");
5681 case CXCursor_OMPTeamsDistributeSimdDirective:
5682 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
5683 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5684 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
5685 case CXCursor_OMPTeamsDistributeParallelForDirective:
5686 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
5687 case CXCursor_OMPTargetTeamsDirective:
5688 return cxstring::createRef("OMPTargetTeamsDirective");
5689 case CXCursor_OMPTargetTeamsDistributeDirective:
5690 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
5691 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5692 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
5693 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5694 return cxstring::createRef(
5695 "OMPTargetTeamsDistributeParallelForSimdDirective");
5696 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5697 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
5698 case CXCursor_OMPInteropDirective:
5699 return cxstring::createRef("OMPInteropDirective");
5700 case CXCursor_OMPDispatchDirective:
5701 return cxstring::createRef("OMPDispatchDirective");
5702 case CXCursor_OMPMaskedDirective:
5703 return cxstring::createRef("OMPMaskedDirective");
5704 case CXCursor_OverloadCandidate:
5705 return cxstring::createRef("OverloadCandidate");
5706 case CXCursor_TypeAliasTemplateDecl:
5707 return cxstring::createRef("TypeAliasTemplateDecl");
5708 case CXCursor_StaticAssert:
5709 return cxstring::createRef("StaticAssert");
5710 case CXCursor_FriendDecl:
5711 return cxstring::createRef("FriendDecl");
5712 case CXCursor_ConvergentAttr:
5713 return cxstring::createRef("attribute(convergent)");
5714 case CXCursor_WarnUnusedAttr:
5715 return cxstring::createRef("attribute(warn_unused)");
5716 case CXCursor_WarnUnusedResultAttr:
5717 return cxstring::createRef("attribute(warn_unused_result)");
5718 case CXCursor_AlignedAttr:
5719 return cxstring::createRef("attribute(aligned)");
5720 }
5721
5722 llvm_unreachable("Unhandled CXCursorKind");
5723 }
5724
5725 struct GetCursorData {
5726 SourceLocation TokenBeginLoc;
5727 bool PointsAtMacroArgExpansion;
5728 bool VisitedObjCPropertyImplDecl;
5729 SourceLocation VisitedDeclaratorDeclStartLoc;
5730 CXCursor &BestCursor;
5731
5732 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5733 CXCursor &outputCursor)
5734 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
5735 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5736 VisitedObjCPropertyImplDecl = false;
5737 }
5738 };
5739
5740 static enum CXChildVisitResult
GetCursorVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)5741 GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
5742 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5743 CXCursor *BestCursor = &Data->BestCursor;
5744
5745 // If we point inside a macro argument we should provide info of what the
5746 // token is so use the actual cursor, don't replace it with a macro expansion
5747 // cursor.
5748 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5749 return CXChildVisit_Recurse;
5750
5751 if (clang_isDeclaration(cursor.kind)) {
5752 // Avoid having the implicit methods override the property decls.
5753 if (const ObjCMethodDecl *MD =
5754 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5755 if (MD->isImplicit())
5756 return CXChildVisit_Break;
5757
5758 } else if (const ObjCInterfaceDecl *ID =
5759 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
5760 // Check that when we have multiple @class references in the same line,
5761 // that later ones do not override the previous ones.
5762 // If we have:
5763 // @class Foo, Bar;
5764 // source ranges for both start at '@', so 'Bar' will end up overriding
5765 // 'Foo' even though the cursor location was at 'Foo'.
5766 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5767 BestCursor->kind == CXCursor_ObjCClassRef)
5768 if (const ObjCInterfaceDecl *PrevID =
5769 dyn_cast_or_null<ObjCInterfaceDecl>(
5770 getCursorDecl(*BestCursor))) {
5771 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5772 !ID->isThisDeclarationADefinition())
5773 return CXChildVisit_Break;
5774 }
5775
5776 } else if (const DeclaratorDecl *DD =
5777 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
5778 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5779 // Check that when we have multiple declarators in the same line,
5780 // that later ones do not override the previous ones.
5781 // If we have:
5782 // int Foo, Bar;
5783 // source ranges for both start at 'int', so 'Bar' will end up overriding
5784 // 'Foo' even though the cursor location was at 'Foo'.
5785 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5786 return CXChildVisit_Break;
5787 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5788
5789 } else if (const ObjCPropertyImplDecl *PropImp =
5790 dyn_cast_or_null<ObjCPropertyImplDecl>(
5791 getCursorDecl(cursor))) {
5792 (void)PropImp;
5793 // Check that when we have multiple @synthesize in the same line,
5794 // that later ones do not override the previous ones.
5795 // If we have:
5796 // @synthesize Foo, Bar;
5797 // source ranges for both start at '@', so 'Bar' will end up overriding
5798 // 'Foo' even though the cursor location was at 'Foo'.
5799 if (Data->VisitedObjCPropertyImplDecl)
5800 return CXChildVisit_Break;
5801 Data->VisitedObjCPropertyImplDecl = true;
5802 }
5803 }
5804
5805 if (clang_isExpression(cursor.kind) &&
5806 clang_isDeclaration(BestCursor->kind)) {
5807 if (const Decl *D = getCursorDecl(*BestCursor)) {
5808 // Avoid having the cursor of an expression replace the declaration cursor
5809 // when the expression source range overlaps the declaration range.
5810 // This can happen for C++ constructor expressions whose range generally
5811 // include the variable declaration, e.g.:
5812 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5813 // cursor.
5814 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5815 D->getLocation() == Data->TokenBeginLoc)
5816 return CXChildVisit_Break;
5817 }
5818 }
5819
5820 // If our current best cursor is the construction of a temporary object,
5821 // don't replace that cursor with a type reference, because we want
5822 // clang_getCursor() to point at the constructor.
5823 if (clang_isExpression(BestCursor->kind) &&
5824 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5825 cursor.kind == CXCursor_TypeRef) {
5826 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5827 // as having the actual point on the type reference.
5828 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5829 return CXChildVisit_Recurse;
5830 }
5831
5832 // If we already have an Objective-C superclass reference, don't
5833 // update it further.
5834 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5835 return CXChildVisit_Break;
5836
5837 *BestCursor = cursor;
5838 return CXChildVisit_Recurse;
5839 }
5840
clang_getCursor(CXTranslationUnit TU,CXSourceLocation Loc)5841 CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
5842 if (isNotUsableTU(TU)) {
5843 LOG_BAD_TU(TU);
5844 return clang_getNullCursor();
5845 }
5846
5847 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5848 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5849
5850 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5851 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5852
5853 LOG_FUNC_SECTION {
5854 CXFile SearchFile;
5855 unsigned SearchLine, SearchColumn;
5856 CXFile ResultFile;
5857 unsigned ResultLine, ResultColumn;
5858 CXString SearchFileName, ResultFileName, KindSpelling, USR;
5859 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
5860 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
5861
5862 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5863 nullptr);
5864 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5865 nullptr);
5866 SearchFileName = clang_getFileName(SearchFile);
5867 ResultFileName = clang_getFileName(ResultFile);
5868 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5869 USR = clang_getCursorUSR(Result);
5870 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5871 SearchLine, SearchColumn,
5872 clang_getCString(KindSpelling))
5873 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5874 ResultLine, ResultColumn, clang_getCString(USR),
5875 IsDef);
5876 clang_disposeString(SearchFileName);
5877 clang_disposeString(ResultFileName);
5878 clang_disposeString(KindSpelling);
5879 clang_disposeString(USR);
5880
5881 CXCursor Definition = clang_getCursorDefinition(Result);
5882 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5883 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5884 CXString DefinitionKindSpelling =
5885 clang_getCursorKindSpelling(Definition.kind);
5886 CXFile DefinitionFile;
5887 unsigned DefinitionLine, DefinitionColumn;
5888 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5889 &DefinitionColumn, nullptr);
5890 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
5891 *Log << llvm::format(" -> %s(%s:%d:%d)",
5892 clang_getCString(DefinitionKindSpelling),
5893 clang_getCString(DefinitionFileName), DefinitionLine,
5894 DefinitionColumn);
5895 clang_disposeString(DefinitionFileName);
5896 clang_disposeString(DefinitionKindSpelling);
5897 }
5898 }
5899
5900 return Result;
5901 }
5902
clang_getNullCursor(void)5903 CXCursor clang_getNullCursor(void) {
5904 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5905 }
5906
clang_equalCursors(CXCursor X,CXCursor Y)5907 unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
5908 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5909 // can't set consistently. For example, when visiting a DeclStmt we will set
5910 // it but we don't set it on the result of clang_getCursorDefinition for
5911 // a reference of the same declaration.
5912 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5913 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5914 // to provide that kind of info.
5915 if (clang_isDeclaration(X.kind))
5916 X.data[1] = nullptr;
5917 if (clang_isDeclaration(Y.kind))
5918 Y.data[1] = nullptr;
5919
5920 return X == Y;
5921 }
5922
clang_hashCursor(CXCursor C)5923 unsigned clang_hashCursor(CXCursor C) {
5924 unsigned Index = 0;
5925 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5926 Index = 1;
5927
5928 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5929 std::make_pair(C.kind, C.data[Index]));
5930 }
5931
clang_isInvalid(enum CXCursorKind K)5932 unsigned clang_isInvalid(enum CXCursorKind K) {
5933 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5934 }
5935
clang_isDeclaration(enum CXCursorKind K)5936 unsigned clang_isDeclaration(enum CXCursorKind K) {
5937 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5938 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5939 }
5940
clang_isInvalidDeclaration(CXCursor C)5941 unsigned clang_isInvalidDeclaration(CXCursor C) {
5942 if (clang_isDeclaration(C.kind)) {
5943 if (const Decl *D = getCursorDecl(C))
5944 return D->isInvalidDecl();
5945 }
5946
5947 return 0;
5948 }
5949
clang_isReference(enum CXCursorKind K)5950 unsigned clang_isReference(enum CXCursorKind K) {
5951 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5952 }
5953
clang_isExpression(enum CXCursorKind K)5954 unsigned clang_isExpression(enum CXCursorKind K) {
5955 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5956 }
5957
clang_isStatement(enum CXCursorKind K)5958 unsigned clang_isStatement(enum CXCursorKind K) {
5959 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5960 }
5961
clang_isAttribute(enum CXCursorKind K)5962 unsigned clang_isAttribute(enum CXCursorKind K) {
5963 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5964 }
5965
clang_isTranslationUnit(enum CXCursorKind K)5966 unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5967 return K == CXCursor_TranslationUnit;
5968 }
5969
clang_isPreprocessing(enum CXCursorKind K)5970 unsigned clang_isPreprocessing(enum CXCursorKind K) {
5971 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5972 }
5973
clang_isUnexposed(enum CXCursorKind K)5974 unsigned clang_isUnexposed(enum CXCursorKind K) {
5975 switch (K) {
5976 case CXCursor_UnexposedDecl:
5977 case CXCursor_UnexposedExpr:
5978 case CXCursor_UnexposedStmt:
5979 case CXCursor_UnexposedAttr:
5980 return true;
5981 default:
5982 return false;
5983 }
5984 }
5985
clang_getCursorKind(CXCursor C)5986 CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
5987
clang_getCursorLocation(CXCursor C)5988 CXSourceLocation clang_getCursorLocation(CXCursor C) {
5989 if (clang_isReference(C.kind)) {
5990 switch (C.kind) {
5991 case CXCursor_ObjCSuperClassRef: {
5992 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5993 getCursorObjCSuperClassRef(C);
5994 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5995 }
5996
5997 case CXCursor_ObjCProtocolRef: {
5998 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5999 getCursorObjCProtocolRef(C);
6000 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6001 }
6002
6003 case CXCursor_ObjCClassRef: {
6004 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
6005 getCursorObjCClassRef(C);
6006 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6007 }
6008
6009 case CXCursor_TypeRef: {
6010 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
6011 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6012 }
6013
6014 case CXCursor_TemplateRef: {
6015 std::pair<const TemplateDecl *, SourceLocation> P =
6016 getCursorTemplateRef(C);
6017 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6018 }
6019
6020 case CXCursor_NamespaceRef: {
6021 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
6022 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6023 }
6024
6025 case CXCursor_MemberRef: {
6026 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
6027 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6028 }
6029
6030 case CXCursor_VariableRef: {
6031 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
6032 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6033 }
6034
6035 case CXCursor_CXXBaseSpecifier: {
6036 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
6037 if (!BaseSpec)
6038 return clang_getNullLocation();
6039
6040 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
6041 return cxloc::translateSourceLocation(
6042 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
6043
6044 return cxloc::translateSourceLocation(getCursorContext(C),
6045 BaseSpec->getBeginLoc());
6046 }
6047
6048 case CXCursor_LabelRef: {
6049 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
6050 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
6051 }
6052
6053 case CXCursor_OverloadedDeclRef:
6054 return cxloc::translateSourceLocation(
6055 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
6056
6057 default:
6058 // FIXME: Need a way to enumerate all non-reference cases.
6059 llvm_unreachable("Missed a reference kind");
6060 }
6061 }
6062
6063 if (clang_isExpression(C.kind))
6064 return cxloc::translateSourceLocation(
6065 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
6066
6067 if (clang_isStatement(C.kind))
6068 return cxloc::translateSourceLocation(getCursorContext(C),
6069 getCursorStmt(C)->getBeginLoc());
6070
6071 if (C.kind == CXCursor_PreprocessingDirective) {
6072 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
6073 return cxloc::translateSourceLocation(getCursorContext(C), L);
6074 }
6075
6076 if (C.kind == CXCursor_MacroExpansion) {
6077 SourceLocation L =
6078 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
6079 return cxloc::translateSourceLocation(getCursorContext(C), L);
6080 }
6081
6082 if (C.kind == CXCursor_MacroDefinition) {
6083 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
6084 return cxloc::translateSourceLocation(getCursorContext(C), L);
6085 }
6086
6087 if (C.kind == CXCursor_InclusionDirective) {
6088 SourceLocation L =
6089 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
6090 return cxloc::translateSourceLocation(getCursorContext(C), L);
6091 }
6092
6093 if (clang_isAttribute(C.kind)) {
6094 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
6095 return cxloc::translateSourceLocation(getCursorContext(C), L);
6096 }
6097
6098 if (!clang_isDeclaration(C.kind))
6099 return clang_getNullLocation();
6100
6101 const Decl *D = getCursorDecl(C);
6102 if (!D)
6103 return clang_getNullLocation();
6104
6105 SourceLocation Loc = D->getLocation();
6106 // FIXME: Multiple variables declared in a single declaration
6107 // currently lack the information needed to correctly determine their
6108 // ranges when accounting for the type-specifier. We use context
6109 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6110 // and if so, whether it is the first decl.
6111 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6112 if (!cxcursor::isFirstInDeclGroup(C))
6113 Loc = VD->getLocation();
6114 }
6115
6116 // For ObjC methods, give the start location of the method name.
6117 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6118 Loc = MD->getSelectorStartLoc();
6119
6120 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
6121 }
6122
6123 } // end extern "C"
6124
getCursor(CXTranslationUnit TU,SourceLocation SLoc)6125 CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6126 assert(TU);
6127
6128 // Guard against an invalid SourceLocation, or we may assert in one
6129 // of the following calls.
6130 if (SLoc.isInvalid())
6131 return clang_getNullCursor();
6132
6133 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6134
6135 // Translate the given source location to make it point at the beginning of
6136 // the token under the cursor.
6137 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6138 CXXUnit->getASTContext().getLangOpts());
6139
6140 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6141 if (SLoc.isValid()) {
6142 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6143 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
6144 /*VisitPreprocessorLast=*/true,
6145 /*VisitIncludedEntities=*/false,
6146 SourceLocation(SLoc));
6147 CursorVis.visitFileRegion();
6148 }
6149
6150 return Result;
6151 }
6152
getRawCursorExtent(CXCursor C)6153 static SourceRange getRawCursorExtent(CXCursor C) {
6154 if (clang_isReference(C.kind)) {
6155 switch (C.kind) {
6156 case CXCursor_ObjCSuperClassRef:
6157 return getCursorObjCSuperClassRef(C).second;
6158
6159 case CXCursor_ObjCProtocolRef:
6160 return getCursorObjCProtocolRef(C).second;
6161
6162 case CXCursor_ObjCClassRef:
6163 return getCursorObjCClassRef(C).second;
6164
6165 case CXCursor_TypeRef:
6166 return getCursorTypeRef(C).second;
6167
6168 case CXCursor_TemplateRef:
6169 return getCursorTemplateRef(C).second;
6170
6171 case CXCursor_NamespaceRef:
6172 return getCursorNamespaceRef(C).second;
6173
6174 case CXCursor_MemberRef:
6175 return getCursorMemberRef(C).second;
6176
6177 case CXCursor_CXXBaseSpecifier:
6178 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6179
6180 case CXCursor_LabelRef:
6181 return getCursorLabelRef(C).second;
6182
6183 case CXCursor_OverloadedDeclRef:
6184 return getCursorOverloadedDeclRef(C).second;
6185
6186 case CXCursor_VariableRef:
6187 return getCursorVariableRef(C).second;
6188
6189 default:
6190 // FIXME: Need a way to enumerate all non-reference cases.
6191 llvm_unreachable("Missed a reference kind");
6192 }
6193 }
6194
6195 if (clang_isExpression(C.kind))
6196 return getCursorExpr(C)->getSourceRange();
6197
6198 if (clang_isStatement(C.kind))
6199 return getCursorStmt(C)->getSourceRange();
6200
6201 if (clang_isAttribute(C.kind))
6202 return getCursorAttr(C)->getRange();
6203
6204 if (C.kind == CXCursor_PreprocessingDirective)
6205 return cxcursor::getCursorPreprocessingDirective(C);
6206
6207 if (C.kind == CXCursor_MacroExpansion) {
6208 ASTUnit *TU = getCursorASTUnit(C);
6209 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
6210 return TU->mapRangeFromPreamble(Range);
6211 }
6212
6213 if (C.kind == CXCursor_MacroDefinition) {
6214 ASTUnit *TU = getCursorASTUnit(C);
6215 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6216 return TU->mapRangeFromPreamble(Range);
6217 }
6218
6219 if (C.kind == CXCursor_InclusionDirective) {
6220 ASTUnit *TU = getCursorASTUnit(C);
6221 SourceRange Range =
6222 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
6223 return TU->mapRangeFromPreamble(Range);
6224 }
6225
6226 if (C.kind == CXCursor_TranslationUnit) {
6227 ASTUnit *TU = getCursorASTUnit(C);
6228 FileID MainID = TU->getSourceManager().getMainFileID();
6229 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6230 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6231 return SourceRange(Start, End);
6232 }
6233
6234 if (clang_isDeclaration(C.kind)) {
6235 const Decl *D = cxcursor::getCursorDecl(C);
6236 if (!D)
6237 return SourceRange();
6238
6239 SourceRange R = D->getSourceRange();
6240 // FIXME: Multiple variables declared in a single declaration
6241 // currently lack the information needed to correctly determine their
6242 // ranges when accounting for the type-specifier. We use context
6243 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6244 // and if so, whether it is the first decl.
6245 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6246 if (!cxcursor::isFirstInDeclGroup(C))
6247 R.setBegin(VD->getLocation());
6248 }
6249 return R;
6250 }
6251 return SourceRange();
6252 }
6253
6254 /// Retrieves the "raw" cursor extent, which is then extended to include
6255 /// the decl-specifier-seq for declarations.
getFullCursorExtent(CXCursor C,SourceManager & SrcMgr)6256 static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6257 if (clang_isDeclaration(C.kind)) {
6258 const Decl *D = cxcursor::getCursorDecl(C);
6259 if (!D)
6260 return SourceRange();
6261
6262 SourceRange R = D->getSourceRange();
6263
6264 // Adjust the start of the location for declarations preceded by
6265 // declaration specifiers.
6266 SourceLocation StartLoc;
6267 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6268 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
6269 StartLoc = TI->getTypeLoc().getBeginLoc();
6270 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
6271 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
6272 StartLoc = TI->getTypeLoc().getBeginLoc();
6273 }
6274
6275 if (StartLoc.isValid() && R.getBegin().isValid() &&
6276 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6277 R.setBegin(StartLoc);
6278
6279 // FIXME: Multiple variables declared in a single declaration
6280 // currently lack the information needed to correctly determine their
6281 // ranges when accounting for the type-specifier. We use context
6282 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6283 // and if so, whether it is the first decl.
6284 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6285 if (!cxcursor::isFirstInDeclGroup(C))
6286 R.setBegin(VD->getLocation());
6287 }
6288
6289 return R;
6290 }
6291
6292 return getRawCursorExtent(C);
6293 }
6294
clang_getCursorExtent(CXCursor C)6295 CXSourceRange clang_getCursorExtent(CXCursor C) {
6296 SourceRange R = getRawCursorExtent(C);
6297 if (R.isInvalid())
6298 return clang_getNullRange();
6299
6300 return cxloc::translateSourceRange(getCursorContext(C), R);
6301 }
6302
clang_getCursorReferenced(CXCursor C)6303 CXCursor clang_getCursorReferenced(CXCursor C) {
6304 if (clang_isInvalid(C.kind))
6305 return clang_getNullCursor();
6306
6307 CXTranslationUnit tu = getCursorTU(C);
6308 if (clang_isDeclaration(C.kind)) {
6309 const Decl *D = getCursorDecl(C);
6310 if (!D)
6311 return clang_getNullCursor();
6312 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
6313 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
6314 if (const ObjCPropertyImplDecl *PropImpl =
6315 dyn_cast<ObjCPropertyImplDecl>(D))
6316 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6317 return MakeCXCursor(Property, tu);
6318
6319 return C;
6320 }
6321
6322 if (clang_isExpression(C.kind)) {
6323 const Expr *E = getCursorExpr(C);
6324 const Decl *D = getDeclFromExpr(E);
6325 if (D) {
6326 CXCursor declCursor = MakeCXCursor(D, tu);
6327 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6328 declCursor);
6329 return declCursor;
6330 }
6331
6332 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
6333 return MakeCursorOverloadedDeclRef(Ovl, tu);
6334
6335 return clang_getNullCursor();
6336 }
6337
6338 if (clang_isStatement(C.kind)) {
6339 const Stmt *S = getCursorStmt(C);
6340 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
6341 if (LabelDecl *label = Goto->getLabel())
6342 if (LabelStmt *labelS = label->getStmt())
6343 return MakeCXCursor(labelS, getCursorDecl(C), tu);
6344
6345 return clang_getNullCursor();
6346 }
6347
6348 if (C.kind == CXCursor_MacroExpansion) {
6349 if (const MacroDefinitionRecord *Def =
6350 getCursorMacroExpansion(C).getDefinition())
6351 return MakeMacroDefinitionCursor(Def, tu);
6352 }
6353
6354 if (!clang_isReference(C.kind))
6355 return clang_getNullCursor();
6356
6357 switch (C.kind) {
6358 case CXCursor_ObjCSuperClassRef:
6359 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
6360
6361 case CXCursor_ObjCProtocolRef: {
6362 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6363 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6364 return MakeCXCursor(Def, tu);
6365
6366 return MakeCXCursor(Prot, tu);
6367 }
6368
6369 case CXCursor_ObjCClassRef: {
6370 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6371 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6372 return MakeCXCursor(Def, tu);
6373
6374 return MakeCXCursor(Class, tu);
6375 }
6376
6377 case CXCursor_TypeRef:
6378 return MakeCXCursor(getCursorTypeRef(C).first, tu);
6379
6380 case CXCursor_TemplateRef:
6381 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
6382
6383 case CXCursor_NamespaceRef:
6384 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
6385
6386 case CXCursor_MemberRef:
6387 return MakeCXCursor(getCursorMemberRef(C).first, tu);
6388
6389 case CXCursor_CXXBaseSpecifier: {
6390 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6391 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6392 }
6393
6394 case CXCursor_LabelRef:
6395 // FIXME: We end up faking the "parent" declaration here because we
6396 // don't want to make CXCursor larger.
6397 return MakeCXCursor(
6398 getCursorLabelRef(C).first,
6399 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
6400
6401 case CXCursor_OverloadedDeclRef:
6402 return C;
6403
6404 case CXCursor_VariableRef:
6405 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6406
6407 default:
6408 // We would prefer to enumerate all non-reference cursor kinds here.
6409 llvm_unreachable("Unhandled reference cursor kind");
6410 }
6411 }
6412
clang_getCursorDefinition(CXCursor C)6413 CXCursor clang_getCursorDefinition(CXCursor C) {
6414 if (clang_isInvalid(C.kind))
6415 return clang_getNullCursor();
6416
6417 CXTranslationUnit TU = getCursorTU(C);
6418
6419 bool WasReference = false;
6420 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6421 C = clang_getCursorReferenced(C);
6422 WasReference = true;
6423 }
6424
6425 if (C.kind == CXCursor_MacroExpansion)
6426 return clang_getCursorReferenced(C);
6427
6428 if (!clang_isDeclaration(C.kind))
6429 return clang_getNullCursor();
6430
6431 const Decl *D = getCursorDecl(C);
6432 if (!D)
6433 return clang_getNullCursor();
6434
6435 switch (D->getKind()) {
6436 // Declaration kinds that don't really separate the notions of
6437 // declaration and definition.
6438 case Decl::Namespace:
6439 case Decl::Typedef:
6440 case Decl::TypeAlias:
6441 case Decl::TypeAliasTemplate:
6442 case Decl::TemplateTypeParm:
6443 case Decl::EnumConstant:
6444 case Decl::Field:
6445 case Decl::Binding:
6446 case Decl::MSProperty:
6447 case Decl::MSGuid:
6448 case Decl::TemplateParamObject:
6449 case Decl::IndirectField:
6450 case Decl::ObjCIvar:
6451 case Decl::ObjCAtDefsField:
6452 case Decl::ImplicitParam:
6453 case Decl::ParmVar:
6454 case Decl::NonTypeTemplateParm:
6455 case Decl::TemplateTemplateParm:
6456 case Decl::ObjCCategoryImpl:
6457 case Decl::ObjCImplementation:
6458 case Decl::AccessSpec:
6459 case Decl::LinkageSpec:
6460 case Decl::Export:
6461 case Decl::ObjCPropertyImpl:
6462 case Decl::FileScopeAsm:
6463 case Decl::StaticAssert:
6464 case Decl::Block:
6465 case Decl::Captured:
6466 case Decl::OMPCapturedExpr:
6467 case Decl::Label: // FIXME: Is this right??
6468 case Decl::ClassScopeFunctionSpecialization:
6469 case Decl::CXXDeductionGuide:
6470 case Decl::Import:
6471 case Decl::OMPThreadPrivate:
6472 case Decl::OMPAllocate:
6473 case Decl::OMPDeclareReduction:
6474 case Decl::OMPDeclareMapper:
6475 case Decl::OMPRequires:
6476 case Decl::ObjCTypeParam:
6477 case Decl::BuiltinTemplate:
6478 case Decl::PragmaComment:
6479 case Decl::PragmaDetectMismatch:
6480 case Decl::UsingPack:
6481 case Decl::Concept:
6482 case Decl::LifetimeExtendedTemporary:
6483 case Decl::RequiresExprBody:
6484 case Decl::UnresolvedUsingIfExists:
6485 return C;
6486
6487 // Declaration kinds that don't make any sense here, but are
6488 // nonetheless harmless.
6489 case Decl::Empty:
6490 case Decl::TranslationUnit:
6491 case Decl::ExternCContext:
6492 break;
6493
6494 // Declaration kinds for which the definition is not resolvable.
6495 case Decl::UnresolvedUsingTypename:
6496 case Decl::UnresolvedUsingValue:
6497 break;
6498
6499 case Decl::UsingDirective:
6500 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6501 TU);
6502
6503 case Decl::NamespaceAlias:
6504 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6505
6506 case Decl::Enum:
6507 case Decl::Record:
6508 case Decl::CXXRecord:
6509 case Decl::ClassTemplateSpecialization:
6510 case Decl::ClassTemplatePartialSpecialization:
6511 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6512 return MakeCXCursor(Def, TU);
6513 return clang_getNullCursor();
6514
6515 case Decl::Function:
6516 case Decl::CXXMethod:
6517 case Decl::CXXConstructor:
6518 case Decl::CXXDestructor:
6519 case Decl::CXXConversion: {
6520 const FunctionDecl *Def = nullptr;
6521 if (cast<FunctionDecl>(D)->getBody(Def))
6522 return MakeCXCursor(Def, TU);
6523 return clang_getNullCursor();
6524 }
6525
6526 case Decl::Var:
6527 case Decl::VarTemplateSpecialization:
6528 case Decl::VarTemplatePartialSpecialization:
6529 case Decl::Decomposition: {
6530 // Ask the variable if it has a definition.
6531 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
6532 return MakeCXCursor(Def, TU);
6533 return clang_getNullCursor();
6534 }
6535
6536 case Decl::FunctionTemplate: {
6537 const FunctionDecl *Def = nullptr;
6538 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6539 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6540 return clang_getNullCursor();
6541 }
6542
6543 case Decl::ClassTemplate: {
6544 if (RecordDecl *Def =
6545 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6546 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6547 TU);
6548 return clang_getNullCursor();
6549 }
6550
6551 case Decl::VarTemplate: {
6552 if (VarDecl *Def =
6553 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6554 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6555 return clang_getNullCursor();
6556 }
6557
6558 case Decl::Using:
6559 case Decl::UsingEnum:
6560 return MakeCursorOverloadedDeclRef(cast<BaseUsingDecl>(D), D->getLocation(),
6561 TU);
6562
6563 case Decl::UsingShadow:
6564 case Decl::ConstructorUsingShadow:
6565 return clang_getCursorDefinition(
6566 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
6567
6568 case Decl::ObjCMethod: {
6569 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
6570 if (Method->isThisDeclarationADefinition())
6571 return C;
6572
6573 // Dig out the method definition in the associated
6574 // @implementation, if we have it.
6575 // FIXME: The ASTs should make finding the definition easier.
6576 if (const ObjCInterfaceDecl *Class =
6577 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
6578 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
6579 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6580 Method->getSelector(), Method->isInstanceMethod()))
6581 if (Def->isThisDeclarationADefinition())
6582 return MakeCXCursor(Def, TU);
6583
6584 return clang_getNullCursor();
6585 }
6586
6587 case Decl::ObjCCategory:
6588 if (ObjCCategoryImplDecl *Impl =
6589 cast<ObjCCategoryDecl>(D)->getImplementation())
6590 return MakeCXCursor(Impl, TU);
6591 return clang_getNullCursor();
6592
6593 case Decl::ObjCProtocol:
6594 if (const ObjCProtocolDecl *Def =
6595 cast<ObjCProtocolDecl>(D)->getDefinition())
6596 return MakeCXCursor(Def, TU);
6597 return clang_getNullCursor();
6598
6599 case Decl::ObjCInterface: {
6600 // There are two notions of a "definition" for an Objective-C
6601 // class: the interface and its implementation. When we resolved a
6602 // reference to an Objective-C class, produce the @interface as
6603 // the definition; when we were provided with the interface,
6604 // produce the @implementation as the definition.
6605 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
6606 if (WasReference) {
6607 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
6608 return MakeCXCursor(Def, TU);
6609 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6610 return MakeCXCursor(Impl, TU);
6611 return clang_getNullCursor();
6612 }
6613
6614 case Decl::ObjCProperty:
6615 // FIXME: We don't really know where to find the
6616 // ObjCPropertyImplDecls that implement this property.
6617 return clang_getNullCursor();
6618
6619 case Decl::ObjCCompatibleAlias:
6620 if (const ObjCInterfaceDecl *Class =
6621 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
6622 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6623 return MakeCXCursor(Def, TU);
6624
6625 return clang_getNullCursor();
6626
6627 case Decl::Friend:
6628 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6629 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6630 return clang_getNullCursor();
6631
6632 case Decl::FriendTemplate:
6633 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6634 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6635 return clang_getNullCursor();
6636 }
6637
6638 return clang_getNullCursor();
6639 }
6640
clang_isCursorDefinition(CXCursor C)6641 unsigned clang_isCursorDefinition(CXCursor C) {
6642 if (!clang_isDeclaration(C.kind))
6643 return 0;
6644
6645 return clang_getCursorDefinition(C) == C;
6646 }
6647
clang_getCanonicalCursor(CXCursor C)6648 CXCursor clang_getCanonicalCursor(CXCursor C) {
6649 if (!clang_isDeclaration(C.kind))
6650 return C;
6651
6652 if (const Decl *D = getCursorDecl(C)) {
6653 if (const ObjCCategoryImplDecl *CatImplD =
6654 dyn_cast<ObjCCategoryImplDecl>(D))
6655 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6656 return MakeCXCursor(CatD, getCursorTU(C));
6657
6658 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6659 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
6660 return MakeCXCursor(IFD, getCursorTU(C));
6661
6662 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6663 }
6664
6665 return C;
6666 }
6667
clang_Cursor_getObjCSelectorIndex(CXCursor cursor)6668 int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6669 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6670 }
6671
clang_getNumOverloadedDecls(CXCursor C)6672 unsigned clang_getNumOverloadedDecls(CXCursor C) {
6673 if (C.kind != CXCursor_OverloadedDeclRef)
6674 return 0;
6675
6676 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
6677 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
6678 return E->getNumDecls();
6679
6680 if (OverloadedTemplateStorage *S =
6681 Storage.dyn_cast<OverloadedTemplateStorage *>())
6682 return S->size();
6683
6684 const Decl *D = Storage.get<const Decl *>();
6685 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
6686 return Using->shadow_size();
6687
6688 return 0;
6689 }
6690
clang_getOverloadedDecl(CXCursor cursor,unsigned index)6691 CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6692 if (cursor.kind != CXCursor_OverloadedDeclRef)
6693 return clang_getNullCursor();
6694
6695 if (index >= clang_getNumOverloadedDecls(cursor))
6696 return clang_getNullCursor();
6697
6698 CXTranslationUnit TU = getCursorTU(cursor);
6699 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
6700 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
6701 return MakeCXCursor(E->decls_begin()[index], TU);
6702
6703 if (OverloadedTemplateStorage *S =
6704 Storage.dyn_cast<OverloadedTemplateStorage *>())
6705 return MakeCXCursor(S->begin()[index], TU);
6706
6707 const Decl *D = Storage.get<const Decl *>();
6708 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
6709 // FIXME: This is, unfortunately, linear time.
6710 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6711 std::advance(Pos, index);
6712 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6713 }
6714
6715 return clang_getNullCursor();
6716 }
6717
clang_getDefinitionSpellingAndExtent(CXCursor C,const char ** startBuf,const char ** endBuf,unsigned * startLine,unsigned * startColumn,unsigned * endLine,unsigned * endColumn)6718 void clang_getDefinitionSpellingAndExtent(
6719 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6720 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
6721 assert(getCursorDecl(C) && "CXCursor has null decl");
6722 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
6723 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6724
6725 SourceManager &SM = FD->getASTContext().getSourceManager();
6726 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6727 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6728 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6729 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6730 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6731 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6732 }
6733
clang_getCursorReferenceNameRange(CXCursor C,unsigned NameFlags,unsigned PieceIndex)6734 CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6735 unsigned PieceIndex) {
6736 RefNamePieces Pieces;
6737
6738 switch (C.kind) {
6739 case CXCursor_MemberRefExpr:
6740 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
6741 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6742 E->getQualifierLoc().getSourceRange());
6743 break;
6744
6745 case CXCursor_DeclRefExpr:
6746 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6747 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6748 Pieces =
6749 buildPieces(NameFlags, false, E->getNameInfo(),
6750 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6751 }
6752 break;
6753
6754 case CXCursor_CallExpr:
6755 if (const CXXOperatorCallExpr *OCE =
6756 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
6757 const Expr *Callee = OCE->getCallee();
6758 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
6759 Callee = ICE->getSubExpr();
6760
6761 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
6762 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6763 DRE->getQualifierLoc().getSourceRange());
6764 }
6765 break;
6766
6767 default:
6768 break;
6769 }
6770
6771 if (Pieces.empty()) {
6772 if (PieceIndex == 0)
6773 return clang_getCursorExtent(C);
6774 } else if (PieceIndex < Pieces.size()) {
6775 SourceRange R = Pieces[PieceIndex];
6776 if (R.isValid())
6777 return cxloc::translateSourceRange(getCursorContext(C), R);
6778 }
6779
6780 return clang_getNullRange();
6781 }
6782
clang_enableStackTraces(void)6783 void clang_enableStackTraces(void) {
6784 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6785 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
6786 }
6787
clang_executeOnThread(void (* fn)(void *),void * user_data,unsigned stack_size)6788 void clang_executeOnThread(void (*fn)(void *), void *user_data,
6789 unsigned stack_size) {
6790 llvm::thread Thread(stack_size == 0 ? clang::DesiredStackSize
6791 : llvm::Optional<unsigned>(stack_size),
6792 fn, user_data);
6793 Thread.join();
6794 }
6795
6796 //===----------------------------------------------------------------------===//
6797 // Token-based Operations.
6798 //===----------------------------------------------------------------------===//
6799
6800 /* CXToken layout:
6801 * int_data[0]: a CXTokenKind
6802 * int_data[1]: starting token location
6803 * int_data[2]: token length
6804 * int_data[3]: reserved
6805 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6806 * otherwise unused.
6807 */
clang_getTokenKind(CXToken CXTok)6808 CXTokenKind clang_getTokenKind(CXToken CXTok) {
6809 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6810 }
6811
clang_getTokenSpelling(CXTranslationUnit TU,CXToken CXTok)6812 CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6813 switch (clang_getTokenKind(CXTok)) {
6814 case CXToken_Identifier:
6815 case CXToken_Keyword:
6816 // We know we have an IdentifierInfo*, so use that.
6817 return cxstring::createRef(
6818 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
6819
6820 case CXToken_Literal: {
6821 // We have stashed the starting pointer in the ptr_data field. Use it.
6822 const char *Text = static_cast<const char *>(CXTok.ptr_data);
6823 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
6824 }
6825
6826 case CXToken_Punctuation:
6827 case CXToken_Comment:
6828 break;
6829 }
6830
6831 if (isNotUsableTU(TU)) {
6832 LOG_BAD_TU(TU);
6833 return cxstring::createEmpty();
6834 }
6835
6836 // We have to find the starting buffer pointer the hard way, by
6837 // deconstructing the source location.
6838 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6839 if (!CXXUnit)
6840 return cxstring::createEmpty();
6841
6842 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
6843 std::pair<FileID, unsigned> LocInfo =
6844 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
6845 bool Invalid = false;
6846 StringRef Buffer =
6847 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
6848 if (Invalid)
6849 return cxstring::createEmpty();
6850
6851 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
6852 }
6853
clang_getTokenLocation(CXTranslationUnit TU,CXToken CXTok)6854 CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
6855 if (isNotUsableTU(TU)) {
6856 LOG_BAD_TU(TU);
6857 return clang_getNullLocation();
6858 }
6859
6860 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6861 if (!CXXUnit)
6862 return clang_getNullLocation();
6863
6864 return cxloc::translateSourceLocation(
6865 CXXUnit->getASTContext(),
6866 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6867 }
6868
clang_getTokenExtent(CXTranslationUnit TU,CXToken CXTok)6869 CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
6870 if (isNotUsableTU(TU)) {
6871 LOG_BAD_TU(TU);
6872 return clang_getNullRange();
6873 }
6874
6875 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6876 if (!CXXUnit)
6877 return clang_getNullRange();
6878
6879 return cxloc::translateSourceRange(
6880 CXXUnit->getASTContext(),
6881 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6882 }
6883
getTokens(ASTUnit * CXXUnit,SourceRange Range,SmallVectorImpl<CXToken> & CXTokens)6884 static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6885 SmallVectorImpl<CXToken> &CXTokens) {
6886 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6887 std::pair<FileID, unsigned> BeginLocInfo =
6888 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6889 std::pair<FileID, unsigned> EndLocInfo =
6890 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
6891
6892 // Cannot tokenize across files.
6893 if (BeginLocInfo.first != EndLocInfo.first)
6894 return;
6895
6896 // Create a lexer
6897 bool Invalid = false;
6898 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6899 if (Invalid)
6900 return;
6901
6902 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6903 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6904 Buffer.data() + BeginLocInfo.second, Buffer.end());
6905 Lex.SetCommentRetentionState(true);
6906
6907 // Lex tokens until we hit the end of the range.
6908 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6909 Token Tok;
6910 bool previousWasAt = false;
6911 do {
6912 // Lex the next token
6913 Lex.LexFromRawLexer(Tok);
6914 if (Tok.is(tok::eof))
6915 break;
6916
6917 // Initialize the CXToken.
6918 CXToken CXTok;
6919
6920 // - Common fields
6921 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6922 CXTok.int_data[2] = Tok.getLength();
6923 CXTok.int_data[3] = 0;
6924
6925 // - Kind-specific fields
6926 if (Tok.isLiteral()) {
6927 CXTok.int_data[0] = CXToken_Literal;
6928 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
6929 } else if (Tok.is(tok::raw_identifier)) {
6930 // Lookup the identifier to determine whether we have a keyword.
6931 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6932
6933 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6934 CXTok.int_data[0] = CXToken_Keyword;
6935 } else {
6936 CXTok.int_data[0] =
6937 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
6938 }
6939 CXTok.ptr_data = II;
6940 } else if (Tok.is(tok::comment)) {
6941 CXTok.int_data[0] = CXToken_Comment;
6942 CXTok.ptr_data = nullptr;
6943 } else {
6944 CXTok.int_data[0] = CXToken_Punctuation;
6945 CXTok.ptr_data = nullptr;
6946 }
6947 CXTokens.push_back(CXTok);
6948 previousWasAt = Tok.is(tok::at);
6949 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
6950 }
6951
clang_getToken(CXTranslationUnit TU,CXSourceLocation Location)6952 CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
6953 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
6954
6955 if (isNotUsableTU(TU)) {
6956 LOG_BAD_TU(TU);
6957 return NULL;
6958 }
6959
6960 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6961 if (!CXXUnit)
6962 return NULL;
6963
6964 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6965 if (Begin.isInvalid())
6966 return NULL;
6967 SourceManager &SM = CXXUnit->getSourceManager();
6968 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
6969 DecomposedEnd.second +=
6970 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
6971
6972 SourceLocation End =
6973 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
6974
6975 SmallVector<CXToken, 32> CXTokens;
6976 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6977
6978 if (CXTokens.empty())
6979 return NULL;
6980
6981 CXTokens.resize(1);
6982 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6983
6984 memmove(Token, CXTokens.data(), sizeof(CXToken));
6985 return Token;
6986 }
6987
clang_tokenize(CXTranslationUnit TU,CXSourceRange Range,CXToken ** Tokens,unsigned * NumTokens)6988 void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6989 unsigned *NumTokens) {
6990 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
6991
6992 if (Tokens)
6993 *Tokens = nullptr;
6994 if (NumTokens)
6995 *NumTokens = 0;
6996
6997 if (isNotUsableTU(TU)) {
6998 LOG_BAD_TU(TU);
6999 return;
7000 }
7001
7002 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7003 if (!CXXUnit || !Tokens || !NumTokens)
7004 return;
7005
7006 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
7007
7008 SourceRange R = cxloc::translateCXSourceRange(Range);
7009 if (R.isInvalid())
7010 return;
7011
7012 SmallVector<CXToken, 32> CXTokens;
7013 getTokens(CXXUnit, R, CXTokens);
7014
7015 if (CXTokens.empty())
7016 return;
7017
7018 *Tokens = static_cast<CXToken *>(
7019 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
7020 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
7021 *NumTokens = CXTokens.size();
7022 }
7023
clang_disposeTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens)7024 void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
7025 unsigned NumTokens) {
7026 free(Tokens);
7027 }
7028
7029 //===----------------------------------------------------------------------===//
7030 // Token annotation APIs.
7031 //===----------------------------------------------------------------------===//
7032
7033 static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7034 CXCursor parent,
7035 CXClientData client_data);
7036 static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7037 CXClientData client_data);
7038
7039 namespace {
7040 class AnnotateTokensWorker {
7041 CXToken *Tokens;
7042 CXCursor *Cursors;
7043 unsigned NumTokens;
7044 unsigned TokIdx;
7045 unsigned PreprocessingTokIdx;
7046 CursorVisitor AnnotateVis;
7047 SourceManager &SrcMgr;
7048 bool HasContextSensitiveKeywords;
7049
7050 struct PostChildrenAction {
7051 CXCursor cursor;
7052 enum Action { Invalid, Ignore, Postpone } action;
7053 };
7054 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
7055
7056 struct PostChildrenInfo {
7057 CXCursor Cursor;
7058 SourceRange CursorRange;
7059 unsigned BeforeReachingCursorIdx;
7060 unsigned BeforeChildrenTokenIdx;
7061 PostChildrenActions ChildActions;
7062 };
7063 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
7064
getTok(unsigned Idx)7065 CXToken &getTok(unsigned Idx) {
7066 assert(Idx < NumTokens);
7067 return Tokens[Idx];
7068 }
getTok(unsigned Idx) const7069 const CXToken &getTok(unsigned Idx) const {
7070 assert(Idx < NumTokens);
7071 return Tokens[Idx];
7072 }
MoreTokens() const7073 bool MoreTokens() const { return TokIdx < NumTokens; }
NextToken() const7074 unsigned NextToken() const { return TokIdx; }
AdvanceToken()7075 void AdvanceToken() { ++TokIdx; }
GetTokenLoc(unsigned tokI)7076 SourceLocation GetTokenLoc(unsigned tokI) {
7077 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
7078 }
isFunctionMacroToken(unsigned tokI) const7079 bool isFunctionMacroToken(unsigned tokI) const {
7080 return getTok(tokI).int_data[3] != 0;
7081 }
getFunctionMacroTokenLoc(unsigned tokI) const7082 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
7083 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
7084 }
7085
7086 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
7087 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
7088 SourceRange);
7089
7090 public:
AnnotateTokensWorker(CXToken * tokens,CXCursor * cursors,unsigned numTokens,CXTranslationUnit TU,SourceRange RegionOfInterest)7091 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
7092 CXTranslationUnit TU, SourceRange RegionOfInterest)
7093 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
7094 PreprocessingTokIdx(0),
7095 AnnotateVis(TU, AnnotateTokensVisitor, this,
7096 /*VisitPreprocessorLast=*/true,
7097 /*VisitIncludedEntities=*/false, RegionOfInterest,
7098 /*VisitDeclsOnly=*/false,
7099 AnnotateTokensPostChildrenVisitor),
7100 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
7101 HasContextSensitiveKeywords(false) {}
7102
VisitChildren(CXCursor C)7103 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
7104 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
7105 bool IsIgnoredChildCursor(CXCursor cursor) const;
7106 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
7107
7108 bool postVisitChildren(CXCursor cursor);
7109 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
7110 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
7111
7112 void AnnotateTokens();
7113
7114 /// Determine whether the annotator saw any cursors that have
7115 /// context-sensitive keywords.
hasContextSensitiveKeywords() const7116 bool hasContextSensitiveKeywords() const {
7117 return HasContextSensitiveKeywords;
7118 }
7119
~AnnotateTokensWorker()7120 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
7121 };
7122 } // namespace
7123
AnnotateTokens()7124 void AnnotateTokensWorker::AnnotateTokens() {
7125 // Walk the AST within the region of interest, annotating tokens
7126 // along the way.
7127 AnnotateVis.visitFileRegion();
7128 }
7129
IsIgnoredChildCursor(CXCursor cursor) const7130 bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7131 if (PostChildrenInfos.empty())
7132 return false;
7133
7134 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7135 if (ChildAction.cursor == cursor &&
7136 ChildAction.action == PostChildrenAction::Ignore) {
7137 return true;
7138 }
7139 }
7140
7141 return false;
7142 }
7143
GetSubscriptOrCallOperator(CXCursor Cursor)7144 const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7145 if (!clang_isExpression(Cursor.kind))
7146 return nullptr;
7147
7148 const Expr *E = getCursorExpr(Cursor);
7149 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7150 const OverloadedOperatorKind Kind = OCE->getOperator();
7151 if (Kind == OO_Call || Kind == OO_Subscript)
7152 return OCE;
7153 }
7154
7155 return nullptr;
7156 }
7157
7158 AnnotateTokensWorker::PostChildrenActions
DetermineChildActions(CXCursor Cursor) const7159 AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7160 PostChildrenActions actions;
7161
7162 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7163 // visited before the arguments to the operator call. For the Call and
7164 // Subscript operator the range of this DeclRefExpr includes the whole call
7165 // expression, so that all tokens in that range would be mapped to the
7166 // operator function, including the tokens of the arguments. To avoid that,
7167 // ensure to visit this DeclRefExpr as last node.
7168 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7169 const Expr *Callee = OCE->getCallee();
7170 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7171 const Expr *SubExpr = ICE->getSubExpr();
7172 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
7173 const Decl *parentDecl = getCursorDecl(Cursor);
7174 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7175
7176 // Visit the DeclRefExpr as last.
7177 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7178 actions.push_back({cxChild, PostChildrenAction::Postpone});
7179
7180 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7181 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7182 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7183 actions.push_back({cxChild, PostChildrenAction::Ignore});
7184 }
7185 }
7186 }
7187
7188 return actions;
7189 }
7190
updateCursorAnnotation(CXCursor & Cursor,const CXCursor & updateC)7191 static inline void updateCursorAnnotation(CXCursor &Cursor,
7192 const CXCursor &updateC) {
7193 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
7194 return;
7195 Cursor = updateC;
7196 }
7197
7198 /// It annotates and advances tokens with a cursor until the comparison
7199 //// between the cursor location and the source range is the same as
7200 /// \arg compResult.
7201 ///
7202 /// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7203 /// Pass RangeOverlap to annotate tokens inside a range.
annotateAndAdvanceTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)7204 void AnnotateTokensWorker::annotateAndAdvanceTokens(
7205 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
7206 while (MoreTokens()) {
7207 const unsigned I = NextToken();
7208 if (isFunctionMacroToken(I))
7209 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7210 return;
7211
7212 SourceLocation TokLoc = GetTokenLoc(I);
7213 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7214 updateCursorAnnotation(Cursors[I], updateC);
7215 AdvanceToken();
7216 continue;
7217 }
7218 break;
7219 }
7220 }
7221
7222 /// Special annotation handling for macro argument tokens.
7223 /// \returns true if it advanced beyond all macro tokens, false otherwise.
annotateAndAdvanceFunctionMacroTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)7224 bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
7225 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
7226 assert(MoreTokens());
7227 assert(isFunctionMacroToken(NextToken()) &&
7228 "Should be called only for macro arg tokens");
7229
7230 // This works differently than annotateAndAdvanceTokens; because expanded
7231 // macro arguments can have arbitrary translation-unit source order, we do not
7232 // advance the token index one by one until a token fails the range test.
7233 // We only advance once past all of the macro arg tokens if all of them
7234 // pass the range test. If one of them fails we keep the token index pointing
7235 // at the start of the macro arg tokens so that the failing token will be
7236 // annotated by a subsequent annotation try.
7237
7238 bool atLeastOneCompFail = false;
7239
7240 unsigned I = NextToken();
7241 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7242 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7243 if (TokLoc.isFileID())
7244 continue; // not macro arg token, it's parens or comma.
7245 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7246 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7247 Cursors[I] = updateC;
7248 } else
7249 atLeastOneCompFail = true;
7250 }
7251
7252 if (atLeastOneCompFail)
7253 return false;
7254
7255 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7256 return true;
7257 }
7258
Visit(CXCursor cursor,CXCursor parent)7259 enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7260 CXCursor parent) {
7261 SourceRange cursorRange = getRawCursorExtent(cursor);
7262 if (cursorRange.isInvalid())
7263 return CXChildVisit_Recurse;
7264
7265 if (IsIgnoredChildCursor(cursor))
7266 return CXChildVisit_Continue;
7267
7268 if (!HasContextSensitiveKeywords) {
7269 // Objective-C properties can have context-sensitive keywords.
7270 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
7271 if (const ObjCPropertyDecl *Property =
7272 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7273 HasContextSensitiveKeywords =
7274 Property->getPropertyAttributesAsWritten() != 0;
7275 }
7276 // Objective-C methods can have context-sensitive keywords.
7277 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7278 cursor.kind == CXCursor_ObjCClassMethodDecl) {
7279 if (const ObjCMethodDecl *Method =
7280 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
7281 if (Method->getObjCDeclQualifier())
7282 HasContextSensitiveKeywords = true;
7283 else {
7284 for (const auto *P : Method->parameters()) {
7285 if (P->getObjCDeclQualifier()) {
7286 HasContextSensitiveKeywords = true;
7287 break;
7288 }
7289 }
7290 }
7291 }
7292 }
7293 // C++ methods can have context-sensitive keywords.
7294 else if (cursor.kind == CXCursor_CXXMethod) {
7295 if (const CXXMethodDecl *Method =
7296 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
7297 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7298 HasContextSensitiveKeywords = true;
7299 }
7300 }
7301 // C++ classes can have context-sensitive keywords.
7302 else if (cursor.kind == CXCursor_StructDecl ||
7303 cursor.kind == CXCursor_ClassDecl ||
7304 cursor.kind == CXCursor_ClassTemplate ||
7305 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
7306 if (const Decl *D = getCursorDecl(cursor))
7307 if (D->hasAttr<FinalAttr>())
7308 HasContextSensitiveKeywords = true;
7309 }
7310 }
7311
7312 // Don't override a property annotation with its getter/setter method.
7313 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7314 parent.kind == CXCursor_ObjCPropertyDecl)
7315 return CXChildVisit_Continue;
7316
7317 if (clang_isPreprocessing(cursor.kind)) {
7318 // Items in the preprocessing record are kept separate from items in
7319 // declarations, so we keep a separate token index.
7320 unsigned SavedTokIdx = TokIdx;
7321 TokIdx = PreprocessingTokIdx;
7322
7323 // Skip tokens up until we catch up to the beginning of the preprocessing
7324 // entry.
7325 while (MoreTokens()) {
7326 const unsigned I = NextToken();
7327 SourceLocation TokLoc = GetTokenLoc(I);
7328 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7329 case RangeBefore:
7330 AdvanceToken();
7331 continue;
7332 case RangeAfter:
7333 case RangeOverlap:
7334 break;
7335 }
7336 break;
7337 }
7338
7339 // Look at all of the tokens within this range.
7340 while (MoreTokens()) {
7341 const unsigned I = NextToken();
7342 SourceLocation TokLoc = GetTokenLoc(I);
7343 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7344 case RangeBefore:
7345 llvm_unreachable("Infeasible");
7346 case RangeAfter:
7347 break;
7348 case RangeOverlap:
7349 // For macro expansions, just note where the beginning of the macro
7350 // expansion occurs.
7351 if (cursor.kind == CXCursor_MacroExpansion) {
7352 if (TokLoc == cursorRange.getBegin())
7353 Cursors[I] = cursor;
7354 AdvanceToken();
7355 break;
7356 }
7357 // We may have already annotated macro names inside macro definitions.
7358 if (Cursors[I].kind != CXCursor_MacroExpansion)
7359 Cursors[I] = cursor;
7360 AdvanceToken();
7361 continue;
7362 }
7363 break;
7364 }
7365
7366 // Save the preprocessing token index; restore the non-preprocessing
7367 // token index.
7368 PreprocessingTokIdx = TokIdx;
7369 TokIdx = SavedTokIdx;
7370 return CXChildVisit_Recurse;
7371 }
7372
7373 if (cursorRange.isInvalid())
7374 return CXChildVisit_Continue;
7375
7376 unsigned BeforeReachingCursorIdx = NextToken();
7377 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
7378 const enum CXCursorKind K = clang_getCursorKind(parent);
7379 const CXCursor updateC =
7380 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7381 // Attributes are annotated out-of-order, skip tokens until we reach it.
7382 clang_isAttribute(cursor.kind))
7383 ? clang_getNullCursor()
7384 : parent;
7385
7386 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7387
7388 // Avoid having the cursor of an expression "overwrite" the annotation of the
7389 // variable declaration that it belongs to.
7390 // This can happen for C++ constructor expressions whose range generally
7391 // include the variable declaration, e.g.:
7392 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
7393 if (clang_isExpression(cursorK) && MoreTokens()) {
7394 const Expr *E = getCursorExpr(cursor);
7395 if (const Decl *D = getCursorDecl(cursor)) {
7396 const unsigned I = NextToken();
7397 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7398 E->getBeginLoc() == D->getLocation() &&
7399 E->getBeginLoc() == GetTokenLoc(I)) {
7400 updateCursorAnnotation(Cursors[I], updateC);
7401 AdvanceToken();
7402 }
7403 }
7404 }
7405
7406 // Before recursing into the children keep some state that we are going
7407 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7408 // extra work after the child nodes are visited.
7409 // Note that we don't call VisitChildren here to avoid traversing statements
7410 // code-recursively which can blow the stack.
7411
7412 PostChildrenInfo Info;
7413 Info.Cursor = cursor;
7414 Info.CursorRange = cursorRange;
7415 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
7416 Info.BeforeChildrenTokenIdx = NextToken();
7417 Info.ChildActions = DetermineChildActions(cursor);
7418 PostChildrenInfos.push_back(Info);
7419
7420 return CXChildVisit_Recurse;
7421 }
7422
postVisitChildren(CXCursor cursor)7423 bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7424 if (PostChildrenInfos.empty())
7425 return false;
7426 const PostChildrenInfo &Info = PostChildrenInfos.back();
7427 if (!clang_equalCursors(Info.Cursor, cursor))
7428 return false;
7429
7430 HandlePostPonedChildCursors(Info);
7431
7432 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7433 const unsigned AfterChildren = NextToken();
7434 SourceRange cursorRange = Info.CursorRange;
7435
7436 // Scan the tokens that are at the end of the cursor, but are not captured
7437 // but the child cursors.
7438 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7439
7440 // Scan the tokens that are at the beginning of the cursor, but are not
7441 // capture by the child cursors.
7442 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7443 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7444 break;
7445
7446 Cursors[I] = cursor;
7447 }
7448
7449 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7450 // encountered the attribute cursor.
7451 if (clang_isAttribute(cursor.kind))
7452 TokIdx = Info.BeforeReachingCursorIdx;
7453
7454 PostChildrenInfos.pop_back();
7455 return false;
7456 }
7457
HandlePostPonedChildCursors(const PostChildrenInfo & Info)7458 void AnnotateTokensWorker::HandlePostPonedChildCursors(
7459 const PostChildrenInfo &Info) {
7460 for (const auto &ChildAction : Info.ChildActions) {
7461 if (ChildAction.action == PostChildrenAction::Postpone) {
7462 HandlePostPonedChildCursor(ChildAction.cursor,
7463 Info.BeforeChildrenTokenIdx);
7464 }
7465 }
7466 }
7467
HandlePostPonedChildCursor(CXCursor Cursor,unsigned StartTokenIndex)7468 void AnnotateTokensWorker::HandlePostPonedChildCursor(
7469 CXCursor Cursor, unsigned StartTokenIndex) {
7470 unsigned I = StartTokenIndex;
7471
7472 // The bracket tokens of a Call or Subscript operator are mapped to
7473 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7474 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7475 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
7476 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7477 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
7478 if (clang_Range_isNull(CXRefNameRange))
7479 break; // All ranges handled.
7480
7481 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7482 while (I < NumTokens) {
7483 const SourceLocation TokenLocation = GetTokenLoc(I);
7484 if (!TokenLocation.isValid())
7485 break;
7486
7487 // Adapt the end range, because LocationCompare() reports
7488 // RangeOverlap even for the not-inclusive end location.
7489 const SourceLocation fixedEnd =
7490 RefNameRange.getEnd().getLocWithOffset(-1);
7491 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7492
7493 const RangeComparisonResult ComparisonResult =
7494 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7495
7496 if (ComparisonResult == RangeOverlap) {
7497 Cursors[I++] = Cursor;
7498 } else if (ComparisonResult == RangeBefore) {
7499 ++I; // Not relevant token, check next one.
7500 } else if (ComparisonResult == RangeAfter) {
7501 break; // All tokens updated for current range, check next.
7502 }
7503 }
7504 }
7505 }
7506
AnnotateTokensVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)7507 static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7508 CXCursor parent,
7509 CXClientData client_data) {
7510 return static_cast<AnnotateTokensWorker *>(client_data)
7511 ->Visit(cursor, parent);
7512 }
7513
AnnotateTokensPostChildrenVisitor(CXCursor cursor,CXClientData client_data)7514 static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7515 CXClientData client_data) {
7516 return static_cast<AnnotateTokensWorker *>(client_data)
7517 ->postVisitChildren(cursor);
7518 }
7519
7520 namespace {
7521
7522 /// Uses the macro expansions in the preprocessing record to find
7523 /// and mark tokens that are macro arguments. This info is used by the
7524 /// AnnotateTokensWorker.
7525 class MarkMacroArgTokensVisitor {
7526 SourceManager &SM;
7527 CXToken *Tokens;
7528 unsigned NumTokens;
7529 unsigned CurIdx;
7530
7531 public:
MarkMacroArgTokensVisitor(SourceManager & SM,CXToken * tokens,unsigned numTokens)7532 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7533 unsigned numTokens)
7534 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
7535
visit(CXCursor cursor,CXCursor parent)7536 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7537 if (cursor.kind != CXCursor_MacroExpansion)
7538 return CXChildVisit_Continue;
7539
7540 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
7541 if (macroRange.getBegin() == macroRange.getEnd())
7542 return CXChildVisit_Continue; // it's not a function macro.
7543
7544 for (; CurIdx < NumTokens; ++CurIdx) {
7545 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7546 macroRange.getBegin()))
7547 break;
7548 }
7549
7550 if (CurIdx == NumTokens)
7551 return CXChildVisit_Break;
7552
7553 for (; CurIdx < NumTokens; ++CurIdx) {
7554 SourceLocation tokLoc = getTokenLoc(CurIdx);
7555 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7556 break;
7557
7558 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7559 }
7560
7561 if (CurIdx == NumTokens)
7562 return CXChildVisit_Break;
7563
7564 return CXChildVisit_Continue;
7565 }
7566
7567 private:
getTok(unsigned Idx)7568 CXToken &getTok(unsigned Idx) {
7569 assert(Idx < NumTokens);
7570 return Tokens[Idx];
7571 }
getTok(unsigned Idx) const7572 const CXToken &getTok(unsigned Idx) const {
7573 assert(Idx < NumTokens);
7574 return Tokens[Idx];
7575 }
7576
getTokenLoc(unsigned tokI)7577 SourceLocation getTokenLoc(unsigned tokI) {
7578 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
7579 }
7580
setFunctionMacroTokenLoc(unsigned tokI,SourceLocation loc)7581 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7582 // The third field is reserved and currently not used. Use it here
7583 // to mark macro arg expanded tokens with their expanded locations.
7584 getTok(tokI).int_data[3] = loc.getRawEncoding();
7585 }
7586 };
7587
7588 } // end anonymous namespace
7589
7590 static CXChildVisitResult
MarkMacroArgTokensVisitorDelegate(CXCursor cursor,CXCursor parent,CXClientData client_data)7591 MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7592 CXClientData client_data) {
7593 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7594 ->visit(cursor, parent);
7595 }
7596
7597 /// Used by \c annotatePreprocessorTokens.
7598 /// \returns true if lexing was finished, false otherwise.
lexNext(Lexer & Lex,Token & Tok,unsigned & NextIdx,unsigned NumTokens)7599 static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7600 unsigned NumTokens) {
7601 if (NextIdx >= NumTokens)
7602 return true;
7603
7604 ++NextIdx;
7605 Lex.LexFromRawLexer(Tok);
7606 return Tok.is(tok::eof);
7607 }
7608
annotatePreprocessorTokens(CXTranslationUnit TU,SourceRange RegionOfInterest,CXCursor * Cursors,CXToken * Tokens,unsigned NumTokens)7609 static void annotatePreprocessorTokens(CXTranslationUnit TU,
7610 SourceRange RegionOfInterest,
7611 CXCursor *Cursors, CXToken *Tokens,
7612 unsigned NumTokens) {
7613 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7614
7615 Preprocessor &PP = CXXUnit->getPreprocessor();
7616 SourceManager &SourceMgr = CXXUnit->getSourceManager();
7617 std::pair<FileID, unsigned> BeginLocInfo =
7618 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7619 std::pair<FileID, unsigned> EndLocInfo =
7620 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
7621
7622 if (BeginLocInfo.first != EndLocInfo.first)
7623 return;
7624
7625 StringRef Buffer;
7626 bool Invalid = false;
7627 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7628 if (Buffer.empty() || Invalid)
7629 return;
7630
7631 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
7632 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7633 Buffer.data() + BeginLocInfo.second, Buffer.end());
7634 Lex.SetCommentRetentionState(true);
7635
7636 unsigned NextIdx = 0;
7637 // Lex tokens in raw mode until we hit the end of the range, to avoid
7638 // entering #includes or expanding macros.
7639 while (true) {
7640 Token Tok;
7641 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7642 break;
7643 unsigned TokIdx = NextIdx - 1;
7644 assert(Tok.getLocation() ==
7645 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7646
7647 reprocess:
7648 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
7649 // We have found a preprocessing directive. Annotate the tokens
7650 // appropriately.
7651 //
7652 // FIXME: Some simple tests here could identify macro definitions and
7653 // #undefs, to provide specific cursor kinds for those.
7654
7655 SourceLocation BeginLoc = Tok.getLocation();
7656 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7657 break;
7658
7659 MacroInfo *MI = nullptr;
7660 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
7661 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7662 break;
7663
7664 if (Tok.is(tok::raw_identifier)) {
7665 IdentifierInfo &II =
7666 PP.getIdentifierTable().get(Tok.getRawIdentifier());
7667 SourceLocation MappedTokLoc =
7668 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7669 MI = getMacroInfo(II, MappedTokLoc, TU);
7670 }
7671 }
7672
7673 bool finished = false;
7674 do {
7675 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7676 finished = true;
7677 break;
7678 }
7679 // If we are in a macro definition, check if the token was ever a
7680 // macro name and annotate it if that's the case.
7681 if (MI) {
7682 SourceLocation SaveLoc = Tok.getLocation();
7683 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
7684 MacroDefinitionRecord *MacroDef =
7685 checkForMacroInMacroDefinition(MI, Tok, TU);
7686 Tok.setLocation(SaveLoc);
7687 if (MacroDef)
7688 Cursors[NextIdx - 1] =
7689 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
7690 }
7691 } while (!Tok.isAtStartOfLine());
7692
7693 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
7694 assert(TokIdx <= LastIdx);
7695 SourceLocation EndLoc =
7696 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7697 CXCursor Cursor =
7698 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7699
7700 for (; TokIdx <= LastIdx; ++TokIdx)
7701 updateCursorAnnotation(Cursors[TokIdx], Cursor);
7702
7703 if (finished)
7704 break;
7705 goto reprocess;
7706 }
7707 }
7708 }
7709
7710 // This gets run a separate thread to avoid stack blowout.
clang_annotateTokensImpl(CXTranslationUnit TU,ASTUnit * CXXUnit,CXToken * Tokens,unsigned NumTokens,CXCursor * Cursors)7711 static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7712 CXToken *Tokens, unsigned NumTokens,
7713 CXCursor *Cursors) {
7714 CIndexer *CXXIdx = TU->CIdx;
7715 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7716 setThreadBackgroundPriority();
7717
7718 // Determine the region of interest, which contains all of the tokens.
7719 SourceRange RegionOfInterest;
7720 RegionOfInterest.setBegin(
7721 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7722 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7723 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
7724
7725 // Relex the tokens within the source range to look for preprocessing
7726 // directives.
7727 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
7728
7729 // If begin location points inside a macro argument, set it to the expansion
7730 // location so we can have the full context when annotating semantically.
7731 {
7732 SourceManager &SM = CXXUnit->getSourceManager();
7733 SourceLocation Loc =
7734 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7735 if (Loc.isMacroID())
7736 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7737 }
7738
7739 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7740 // Search and mark tokens that are macro argument expansions.
7741 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7742 NumTokens);
7743 CursorVisitor MacroArgMarker(
7744 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7745 /*VisitPreprocessorLast=*/true,
7746 /*VisitIncludedEntities=*/false, RegionOfInterest);
7747 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7748 }
7749
7750 // Annotate all of the source locations in the region of interest that map to
7751 // a specific cursor.
7752 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
7753
7754 // FIXME: We use a ridiculous stack size here because the data-recursion
7755 // algorithm uses a large stack frame than the non-data recursive version,
7756 // and AnnotationTokensWorker currently transforms the data-recursion
7757 // algorithm back into a traditional recursion by explicitly calling
7758 // VisitChildren(). We will need to remove this explicit recursive call.
7759 W.AnnotateTokens();
7760
7761 // If we ran into any entities that involve context-sensitive keywords,
7762 // take another pass through the tokens to mark them as such.
7763 if (W.hasContextSensitiveKeywords()) {
7764 for (unsigned I = 0; I != NumTokens; ++I) {
7765 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7766 continue;
7767
7768 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7769 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7770 if (const ObjCPropertyDecl *Property =
7771 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
7772 if (Property->getPropertyAttributesAsWritten() != 0 &&
7773 llvm::StringSwitch<bool>(II->getName())
7774 .Case("readonly", true)
7775 .Case("assign", true)
7776 .Case("unsafe_unretained", true)
7777 .Case("readwrite", true)
7778 .Case("retain", true)
7779 .Case("copy", true)
7780 .Case("nonatomic", true)
7781 .Case("atomic", true)
7782 .Case("getter", true)
7783 .Case("setter", true)
7784 .Case("strong", true)
7785 .Case("weak", true)
7786 .Case("class", true)
7787 .Default(false))
7788 Tokens[I].int_data[0] = CXToken_Keyword;
7789 }
7790 continue;
7791 }
7792
7793 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7794 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7795 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7796 if (llvm::StringSwitch<bool>(II->getName())
7797 .Case("in", true)
7798 .Case("out", true)
7799 .Case("inout", true)
7800 .Case("oneway", true)
7801 .Case("bycopy", true)
7802 .Case("byref", true)
7803 .Default(false))
7804 Tokens[I].int_data[0] = CXToken_Keyword;
7805 continue;
7806 }
7807
7808 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7809 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7810 Tokens[I].int_data[0] = CXToken_Keyword;
7811 continue;
7812 }
7813 }
7814 }
7815 }
7816
clang_annotateTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens,CXCursor * Cursors)7817 void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7818 unsigned NumTokens, CXCursor *Cursors) {
7819 if (isNotUsableTU(TU)) {
7820 LOG_BAD_TU(TU);
7821 return;
7822 }
7823 if (NumTokens == 0 || !Tokens || !Cursors) {
7824 LOG_FUNC_SECTION { *Log << "<null input>"; }
7825 return;
7826 }
7827
7828 LOG_FUNC_SECTION {
7829 *Log << TU << ' ';
7830 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
7831 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
7832 *Log << clang_getRange(bloc, eloc);
7833 }
7834
7835 // Any token we don't specifically annotate will have a NULL cursor.
7836 CXCursor C = clang_getNullCursor();
7837 for (unsigned I = 0; I != NumTokens; ++I)
7838 Cursors[I] = C;
7839
7840 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7841 if (!CXXUnit)
7842 return;
7843
7844 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
7845
7846 auto AnnotateTokensImpl = [=]() {
7847 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7848 };
7849 llvm::CrashRecoveryContext CRC;
7850 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
7851 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7852 }
7853 }
7854
7855 //===----------------------------------------------------------------------===//
7856 // Operations for querying linkage of a cursor.
7857 //===----------------------------------------------------------------------===//
7858
clang_getCursorLinkage(CXCursor cursor)7859 CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7860 if (!clang_isDeclaration(cursor.kind))
7861 return CXLinkage_Invalid;
7862
7863 const Decl *D = cxcursor::getCursorDecl(cursor);
7864 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7865 switch (ND->getLinkageInternal()) {
7866 case NoLinkage:
7867 case VisibleNoLinkage:
7868 return CXLinkage_NoLinkage;
7869 case ModuleInternalLinkage:
7870 case InternalLinkage:
7871 return CXLinkage_Internal;
7872 case UniqueExternalLinkage:
7873 return CXLinkage_UniqueExternal;
7874 case ModuleLinkage:
7875 case ExternalLinkage:
7876 return CXLinkage_External;
7877 };
7878
7879 return CXLinkage_Invalid;
7880 }
7881
7882 //===----------------------------------------------------------------------===//
7883 // Operations for querying visibility of a cursor.
7884 //===----------------------------------------------------------------------===//
7885
clang_getCursorVisibility(CXCursor cursor)7886 CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7887 if (!clang_isDeclaration(cursor.kind))
7888 return CXVisibility_Invalid;
7889
7890 const Decl *D = cxcursor::getCursorDecl(cursor);
7891 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7892 switch (ND->getVisibility()) {
7893 case HiddenVisibility:
7894 return CXVisibility_Hidden;
7895 case ProtectedVisibility:
7896 return CXVisibility_Protected;
7897 case DefaultVisibility:
7898 return CXVisibility_Default;
7899 };
7900
7901 return CXVisibility_Invalid;
7902 }
7903
7904 //===----------------------------------------------------------------------===//
7905 // Operations for querying language of a cursor.
7906 //===----------------------------------------------------------------------===//
7907
getDeclLanguage(const Decl * D)7908 static CXLanguageKind getDeclLanguage(const Decl *D) {
7909 if (!D)
7910 return CXLanguage_C;
7911
7912 switch (D->getKind()) {
7913 default:
7914 break;
7915 case Decl::ImplicitParam:
7916 case Decl::ObjCAtDefsField:
7917 case Decl::ObjCCategory:
7918 case Decl::ObjCCategoryImpl:
7919 case Decl::ObjCCompatibleAlias:
7920 case Decl::ObjCImplementation:
7921 case Decl::ObjCInterface:
7922 case Decl::ObjCIvar:
7923 case Decl::ObjCMethod:
7924 case Decl::ObjCProperty:
7925 case Decl::ObjCPropertyImpl:
7926 case Decl::ObjCProtocol:
7927 case Decl::ObjCTypeParam:
7928 return CXLanguage_ObjC;
7929 case Decl::CXXConstructor:
7930 case Decl::CXXConversion:
7931 case Decl::CXXDestructor:
7932 case Decl::CXXMethod:
7933 case Decl::CXXRecord:
7934 case Decl::ClassTemplate:
7935 case Decl::ClassTemplatePartialSpecialization:
7936 case Decl::ClassTemplateSpecialization:
7937 case Decl::Friend:
7938 case Decl::FriendTemplate:
7939 case Decl::FunctionTemplate:
7940 case Decl::LinkageSpec:
7941 case Decl::Namespace:
7942 case Decl::NamespaceAlias:
7943 case Decl::NonTypeTemplateParm:
7944 case Decl::StaticAssert:
7945 case Decl::TemplateTemplateParm:
7946 case Decl::TemplateTypeParm:
7947 case Decl::UnresolvedUsingTypename:
7948 case Decl::UnresolvedUsingValue:
7949 case Decl::Using:
7950 case Decl::UsingDirective:
7951 case Decl::UsingShadow:
7952 return CXLanguage_CPlusPlus;
7953 }
7954
7955 return CXLanguage_C;
7956 }
7957
getCursorAvailabilityForDecl(const Decl * D)7958 static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7959 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
7960 return CXAvailability_NotAvailable;
7961
7962 switch (D->getAvailability()) {
7963 case AR_Available:
7964 case AR_NotYetIntroduced:
7965 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7966 return getCursorAvailabilityForDecl(
7967 cast<Decl>(EnumConst->getDeclContext()));
7968 return CXAvailability_Available;
7969
7970 case AR_Deprecated:
7971 return CXAvailability_Deprecated;
7972
7973 case AR_Unavailable:
7974 return CXAvailability_NotAvailable;
7975 }
7976
7977 llvm_unreachable("Unknown availability kind!");
7978 }
7979
clang_getCursorAvailability(CXCursor cursor)7980 enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7981 if (clang_isDeclaration(cursor.kind))
7982 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7983 return getCursorAvailabilityForDecl(D);
7984
7985 return CXAvailability_Available;
7986 }
7987
convertVersion(VersionTuple In)7988 static CXVersion convertVersion(VersionTuple In) {
7989 CXVersion Out = {-1, -1, -1};
7990 if (In.empty())
7991 return Out;
7992
7993 Out.Major = In.getMajor();
7994
7995 Optional<unsigned> Minor = In.getMinor();
7996 if (Minor.hasValue())
7997 Out.Minor = *Minor;
7998 else
7999 return Out;
8000
8001 Optional<unsigned> Subminor = In.getSubminor();
8002 if (Subminor.hasValue())
8003 Out.Subminor = *Subminor;
8004
8005 return Out;
8006 }
8007
getCursorPlatformAvailabilityForDecl(const Decl * D,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,SmallVectorImpl<AvailabilityAttr * > & AvailabilityAttrs)8008 static void getCursorPlatformAvailabilityForDecl(
8009 const Decl *D, int *always_deprecated, CXString *deprecated_message,
8010 int *always_unavailable, CXString *unavailable_message,
8011 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
8012 bool HadAvailAttr = false;
8013 for (auto A : D->attrs()) {
8014 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
8015 HadAvailAttr = true;
8016 if (always_deprecated)
8017 *always_deprecated = 1;
8018 if (deprecated_message) {
8019 clang_disposeString(*deprecated_message);
8020 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
8021 }
8022 continue;
8023 }
8024
8025 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
8026 HadAvailAttr = true;
8027 if (always_unavailable)
8028 *always_unavailable = 1;
8029 if (unavailable_message) {
8030 clang_disposeString(*unavailable_message);
8031 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
8032 }
8033 continue;
8034 }
8035
8036 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
8037 AvailabilityAttrs.push_back(Avail);
8038 HadAvailAttr = true;
8039 }
8040 }
8041
8042 if (!HadAvailAttr)
8043 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
8044 return getCursorPlatformAvailabilityForDecl(
8045 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
8046 deprecated_message, always_unavailable, unavailable_message,
8047 AvailabilityAttrs);
8048
8049 if (AvailabilityAttrs.empty())
8050 return;
8051
8052 llvm::sort(
8053 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
8054 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
8055 });
8056 ASTContext &Ctx = D->getASTContext();
8057 auto It = std::unique(
8058 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
8059 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
8060 if (LHS->getPlatform() != RHS->getPlatform())
8061 return false;
8062
8063 if (LHS->getIntroduced() == RHS->getIntroduced() &&
8064 LHS->getDeprecated() == RHS->getDeprecated() &&
8065 LHS->getObsoleted() == RHS->getObsoleted() &&
8066 LHS->getMessage() == RHS->getMessage() &&
8067 LHS->getReplacement() == RHS->getReplacement())
8068 return true;
8069
8070 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
8071 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
8072 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
8073 return false;
8074
8075 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
8076 LHS->setIntroduced(Ctx, RHS->getIntroduced());
8077
8078 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
8079 LHS->setDeprecated(Ctx, RHS->getDeprecated());
8080 if (LHS->getMessage().empty())
8081 LHS->setMessage(Ctx, RHS->getMessage());
8082 if (LHS->getReplacement().empty())
8083 LHS->setReplacement(Ctx, RHS->getReplacement());
8084 }
8085
8086 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
8087 LHS->setObsoleted(Ctx, RHS->getObsoleted());
8088 if (LHS->getMessage().empty())
8089 LHS->setMessage(Ctx, RHS->getMessage());
8090 if (LHS->getReplacement().empty())
8091 LHS->setReplacement(Ctx, RHS->getReplacement());
8092 }
8093
8094 return true;
8095 });
8096 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
8097 }
8098
clang_getCursorPlatformAvailability(CXCursor cursor,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,CXPlatformAvailability * availability,int availability_size)8099 int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
8100 CXString *deprecated_message,
8101 int *always_unavailable,
8102 CXString *unavailable_message,
8103 CXPlatformAvailability *availability,
8104 int availability_size) {
8105 if (always_deprecated)
8106 *always_deprecated = 0;
8107 if (deprecated_message)
8108 *deprecated_message = cxstring::createEmpty();
8109 if (always_unavailable)
8110 *always_unavailable = 0;
8111 if (unavailable_message)
8112 *unavailable_message = cxstring::createEmpty();
8113
8114 if (!clang_isDeclaration(cursor.kind))
8115 return 0;
8116
8117 const Decl *D = cxcursor::getCursorDecl(cursor);
8118 if (!D)
8119 return 0;
8120
8121 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
8122 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8123 always_unavailable, unavailable_message,
8124 AvailabilityAttrs);
8125 for (const auto &Avail :
8126 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8127 .take_front(availability_size))) {
8128 availability[Avail.index()].Platform =
8129 cxstring::createDup(Avail.value()->getPlatform()->getName());
8130 availability[Avail.index()].Introduced =
8131 convertVersion(Avail.value()->getIntroduced());
8132 availability[Avail.index()].Deprecated =
8133 convertVersion(Avail.value()->getDeprecated());
8134 availability[Avail.index()].Obsoleted =
8135 convertVersion(Avail.value()->getObsoleted());
8136 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8137 availability[Avail.index()].Message =
8138 cxstring::createDup(Avail.value()->getMessage());
8139 }
8140
8141 return AvailabilityAttrs.size();
8142 }
8143
clang_disposeCXPlatformAvailability(CXPlatformAvailability * availability)8144 void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8145 clang_disposeString(availability->Platform);
8146 clang_disposeString(availability->Message);
8147 }
8148
clang_getCursorLanguage(CXCursor cursor)8149 CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8150 if (clang_isDeclaration(cursor.kind))
8151 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8152
8153 return CXLanguage_Invalid;
8154 }
8155
clang_getCursorTLSKind(CXCursor cursor)8156 CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8157 const Decl *D = cxcursor::getCursorDecl(cursor);
8158 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8159 switch (VD->getTLSKind()) {
8160 case VarDecl::TLS_None:
8161 return CXTLS_None;
8162 case VarDecl::TLS_Dynamic:
8163 return CXTLS_Dynamic;
8164 case VarDecl::TLS_Static:
8165 return CXTLS_Static;
8166 }
8167 }
8168
8169 return CXTLS_None;
8170 }
8171
8172 /// If the given cursor is the "templated" declaration
8173 /// describing a class or function template, return the class or
8174 /// function template.
maybeGetTemplateCursor(const Decl * D)8175 static const Decl *maybeGetTemplateCursor(const Decl *D) {
8176 if (!D)
8177 return nullptr;
8178
8179 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8180 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8181 return FunTmpl;
8182
8183 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
8184 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8185 return ClassTmpl;
8186
8187 return D;
8188 }
8189
clang_Cursor_getStorageClass(CXCursor C)8190 enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8191 StorageClass sc = SC_None;
8192 const Decl *D = getCursorDecl(C);
8193 if (D) {
8194 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8195 sc = FD->getStorageClass();
8196 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8197 sc = VD->getStorageClass();
8198 } else {
8199 return CX_SC_Invalid;
8200 }
8201 } else {
8202 return CX_SC_Invalid;
8203 }
8204 switch (sc) {
8205 case SC_None:
8206 return CX_SC_None;
8207 case SC_Extern:
8208 return CX_SC_Extern;
8209 case SC_Static:
8210 return CX_SC_Static;
8211 case SC_PrivateExtern:
8212 return CX_SC_PrivateExtern;
8213 case SC_Auto:
8214 return CX_SC_Auto;
8215 case SC_Register:
8216 return CX_SC_Register;
8217 }
8218 llvm_unreachable("Unhandled storage class!");
8219 }
8220
clang_getCursorSemanticParent(CXCursor cursor)8221 CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8222 if (clang_isDeclaration(cursor.kind)) {
8223 if (const Decl *D = getCursorDecl(cursor)) {
8224 const DeclContext *DC = D->getDeclContext();
8225 if (!DC)
8226 return clang_getNullCursor();
8227
8228 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
8229 getCursorTU(cursor));
8230 }
8231 }
8232
8233 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
8234 if (const Decl *D = getCursorDecl(cursor))
8235 return MakeCXCursor(D, getCursorTU(cursor));
8236 }
8237
8238 return clang_getNullCursor();
8239 }
8240
clang_getCursorLexicalParent(CXCursor cursor)8241 CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8242 if (clang_isDeclaration(cursor.kind)) {
8243 if (const Decl *D = getCursorDecl(cursor)) {
8244 const DeclContext *DC = D->getLexicalDeclContext();
8245 if (!DC)
8246 return clang_getNullCursor();
8247
8248 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
8249 getCursorTU(cursor));
8250 }
8251 }
8252
8253 // FIXME: Note that we can't easily compute the lexical context of a
8254 // statement or expression, so we return nothing.
8255 return clang_getNullCursor();
8256 }
8257
clang_getIncludedFile(CXCursor cursor)8258 CXFile clang_getIncludedFile(CXCursor cursor) {
8259 if (cursor.kind != CXCursor_InclusionDirective)
8260 return nullptr;
8261
8262 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
8263 return const_cast<FileEntry *>(ID->getFile());
8264 }
8265
clang_Cursor_getObjCPropertyAttributes(CXCursor C,unsigned reserved)8266 unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8267 if (C.kind != CXCursor_ObjCPropertyDecl)
8268 return CXObjCPropertyAttr_noattr;
8269
8270 unsigned Result = CXObjCPropertyAttr_noattr;
8271 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8272 ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
8273
8274 #define SET_CXOBJCPROP_ATTR(A) \
8275 if (Attr & ObjCPropertyAttribute::kind_##A) \
8276 Result |= CXObjCPropertyAttr_##A
8277 SET_CXOBJCPROP_ATTR(readonly);
8278 SET_CXOBJCPROP_ATTR(getter);
8279 SET_CXOBJCPROP_ATTR(assign);
8280 SET_CXOBJCPROP_ATTR(readwrite);
8281 SET_CXOBJCPROP_ATTR(retain);
8282 SET_CXOBJCPROP_ATTR(copy);
8283 SET_CXOBJCPROP_ATTR(nonatomic);
8284 SET_CXOBJCPROP_ATTR(setter);
8285 SET_CXOBJCPROP_ATTR(atomic);
8286 SET_CXOBJCPROP_ATTR(weak);
8287 SET_CXOBJCPROP_ATTR(strong);
8288 SET_CXOBJCPROP_ATTR(unsafe_unretained);
8289 SET_CXOBJCPROP_ATTR(class);
8290 #undef SET_CXOBJCPROP_ATTR
8291
8292 return Result;
8293 }
8294
clang_Cursor_getObjCPropertyGetterName(CXCursor C)8295 CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8296 if (C.kind != CXCursor_ObjCPropertyDecl)
8297 return cxstring::createNull();
8298
8299 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8300 Selector sel = PD->getGetterName();
8301 if (sel.isNull())
8302 return cxstring::createNull();
8303
8304 return cxstring::createDup(sel.getAsString());
8305 }
8306
clang_Cursor_getObjCPropertySetterName(CXCursor C)8307 CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8308 if (C.kind != CXCursor_ObjCPropertyDecl)
8309 return cxstring::createNull();
8310
8311 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8312 Selector sel = PD->getSetterName();
8313 if (sel.isNull())
8314 return cxstring::createNull();
8315
8316 return cxstring::createDup(sel.getAsString());
8317 }
8318
clang_Cursor_getObjCDeclQualifiers(CXCursor C)8319 unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8320 if (!clang_isDeclaration(C.kind))
8321 return CXObjCDeclQualifier_None;
8322
8323 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8324 const Decl *D = getCursorDecl(C);
8325 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8326 QT = MD->getObjCDeclQualifier();
8327 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8328 QT = PD->getObjCDeclQualifier();
8329 if (QT == Decl::OBJC_TQ_None)
8330 return CXObjCDeclQualifier_None;
8331
8332 unsigned Result = CXObjCDeclQualifier_None;
8333 if (QT & Decl::OBJC_TQ_In)
8334 Result |= CXObjCDeclQualifier_In;
8335 if (QT & Decl::OBJC_TQ_Inout)
8336 Result |= CXObjCDeclQualifier_Inout;
8337 if (QT & Decl::OBJC_TQ_Out)
8338 Result |= CXObjCDeclQualifier_Out;
8339 if (QT & Decl::OBJC_TQ_Bycopy)
8340 Result |= CXObjCDeclQualifier_Bycopy;
8341 if (QT & Decl::OBJC_TQ_Byref)
8342 Result |= CXObjCDeclQualifier_Byref;
8343 if (QT & Decl::OBJC_TQ_Oneway)
8344 Result |= CXObjCDeclQualifier_Oneway;
8345
8346 return Result;
8347 }
8348
clang_Cursor_isObjCOptional(CXCursor C)8349 unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8350 if (!clang_isDeclaration(C.kind))
8351 return 0;
8352
8353 const Decl *D = getCursorDecl(C);
8354 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8355 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8356 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8357 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8358
8359 return 0;
8360 }
8361
clang_Cursor_isVariadic(CXCursor C)8362 unsigned clang_Cursor_isVariadic(CXCursor C) {
8363 if (!clang_isDeclaration(C.kind))
8364 return 0;
8365
8366 const Decl *D = getCursorDecl(C);
8367 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8368 return FD->isVariadic();
8369 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8370 return MD->isVariadic();
8371
8372 return 0;
8373 }
8374
clang_Cursor_isExternalSymbol(CXCursor C,CXString * language,CXString * definedIn,unsigned * isGenerated)8375 unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8376 CXString *definedIn,
8377 unsigned *isGenerated) {
8378 if (!clang_isDeclaration(C.kind))
8379 return 0;
8380
8381 const Decl *D = getCursorDecl(C);
8382
8383 if (auto *attr = D->getExternalSourceSymbolAttr()) {
8384 if (language)
8385 *language = cxstring::createDup(attr->getLanguage());
8386 if (definedIn)
8387 *definedIn = cxstring::createDup(attr->getDefinedIn());
8388 if (isGenerated)
8389 *isGenerated = attr->getGeneratedDeclaration();
8390 return 1;
8391 }
8392 return 0;
8393 }
8394
clang_Cursor_getCommentRange(CXCursor C)8395 CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8396 if (!clang_isDeclaration(C.kind))
8397 return clang_getNullRange();
8398
8399 const Decl *D = getCursorDecl(C);
8400 ASTContext &Context = getCursorContext(C);
8401 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8402 if (!RC)
8403 return clang_getNullRange();
8404
8405 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8406 }
8407
clang_Cursor_getRawCommentText(CXCursor C)8408 CXString clang_Cursor_getRawCommentText(CXCursor C) {
8409 if (!clang_isDeclaration(C.kind))
8410 return cxstring::createNull();
8411
8412 const Decl *D = getCursorDecl(C);
8413 ASTContext &Context = getCursorContext(C);
8414 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8415 StringRef RawText =
8416 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
8417
8418 // Don't duplicate the string because RawText points directly into source
8419 // code.
8420 return cxstring::createRef(RawText);
8421 }
8422
clang_Cursor_getBriefCommentText(CXCursor C)8423 CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8424 if (!clang_isDeclaration(C.kind))
8425 return cxstring::createNull();
8426
8427 const Decl *D = getCursorDecl(C);
8428 const ASTContext &Context = getCursorContext(C);
8429 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8430
8431 if (RC) {
8432 StringRef BriefText = RC->getBriefText(Context);
8433
8434 // Don't duplicate the string because RawComment ensures that this memory
8435 // will not go away.
8436 return cxstring::createRef(BriefText);
8437 }
8438
8439 return cxstring::createNull();
8440 }
8441
clang_Cursor_getModule(CXCursor C)8442 CXModule clang_Cursor_getModule(CXCursor C) {
8443 if (C.kind == CXCursor_ModuleImportDecl) {
8444 if (const ImportDecl *ImportD =
8445 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
8446 return ImportD->getImportedModule();
8447 }
8448
8449 return nullptr;
8450 }
8451
clang_getModuleForFile(CXTranslationUnit TU,CXFile File)8452 CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8453 if (isNotUsableTU(TU)) {
8454 LOG_BAD_TU(TU);
8455 return nullptr;
8456 }
8457 if (!File)
8458 return nullptr;
8459 FileEntry *FE = static_cast<FileEntry *>(File);
8460
8461 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8462 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8463 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
8464
8465 return Header.getModule();
8466 }
8467
clang_Module_getASTFile(CXModule CXMod)8468 CXFile clang_Module_getASTFile(CXModule CXMod) {
8469 if (!CXMod)
8470 return nullptr;
8471 Module *Mod = static_cast<Module *>(CXMod);
8472 if (auto File = Mod->getASTFile())
8473 return const_cast<FileEntry *>(&File->getFileEntry());
8474 return nullptr;
8475 }
8476
clang_Module_getParent(CXModule CXMod)8477 CXModule clang_Module_getParent(CXModule CXMod) {
8478 if (!CXMod)
8479 return nullptr;
8480 Module *Mod = static_cast<Module *>(CXMod);
8481 return Mod->Parent;
8482 }
8483
clang_Module_getName(CXModule CXMod)8484 CXString clang_Module_getName(CXModule CXMod) {
8485 if (!CXMod)
8486 return cxstring::createEmpty();
8487 Module *Mod = static_cast<Module *>(CXMod);
8488 return cxstring::createDup(Mod->Name);
8489 }
8490
clang_Module_getFullName(CXModule CXMod)8491 CXString clang_Module_getFullName(CXModule CXMod) {
8492 if (!CXMod)
8493 return cxstring::createEmpty();
8494 Module *Mod = static_cast<Module *>(CXMod);
8495 return cxstring::createDup(Mod->getFullModuleName());
8496 }
8497
clang_Module_isSystem(CXModule CXMod)8498 int clang_Module_isSystem(CXModule CXMod) {
8499 if (!CXMod)
8500 return 0;
8501 Module *Mod = static_cast<Module *>(CXMod);
8502 return Mod->IsSystem;
8503 }
8504
clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,CXModule CXMod)8505 unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8506 CXModule CXMod) {
8507 if (isNotUsableTU(TU)) {
8508 LOG_BAD_TU(TU);
8509 return 0;
8510 }
8511 if (!CXMod)
8512 return 0;
8513 Module *Mod = static_cast<Module *>(CXMod);
8514 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8515 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8516 return TopHeaders.size();
8517 }
8518
clang_Module_getTopLevelHeader(CXTranslationUnit TU,CXModule CXMod,unsigned Index)8519 CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8520 unsigned Index) {
8521 if (isNotUsableTU(TU)) {
8522 LOG_BAD_TU(TU);
8523 return nullptr;
8524 }
8525 if (!CXMod)
8526 return nullptr;
8527 Module *Mod = static_cast<Module *>(CXMod);
8528 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8529
8530 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8531 if (Index < TopHeaders.size())
8532 return const_cast<FileEntry *>(TopHeaders[Index]);
8533
8534 return nullptr;
8535 }
8536
8537 //===----------------------------------------------------------------------===//
8538 // C++ AST instrospection.
8539 //===----------------------------------------------------------------------===//
8540
clang_CXXConstructor_isDefaultConstructor(CXCursor C)8541 unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8542 if (!clang_isDeclaration(C.kind))
8543 return 0;
8544
8545 const Decl *D = cxcursor::getCursorDecl(C);
8546 const CXXConstructorDecl *Constructor =
8547 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8548 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8549 }
8550
clang_CXXConstructor_isCopyConstructor(CXCursor C)8551 unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8552 if (!clang_isDeclaration(C.kind))
8553 return 0;
8554
8555 const Decl *D = cxcursor::getCursorDecl(C);
8556 const CXXConstructorDecl *Constructor =
8557 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8558 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8559 }
8560
clang_CXXConstructor_isMoveConstructor(CXCursor C)8561 unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8562 if (!clang_isDeclaration(C.kind))
8563 return 0;
8564
8565 const Decl *D = cxcursor::getCursorDecl(C);
8566 const CXXConstructorDecl *Constructor =
8567 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8568 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8569 }
8570
clang_CXXConstructor_isConvertingConstructor(CXCursor C)8571 unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8572 if (!clang_isDeclaration(C.kind))
8573 return 0;
8574
8575 const Decl *D = cxcursor::getCursorDecl(C);
8576 const CXXConstructorDecl *Constructor =
8577 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8578 // Passing 'false' excludes constructors marked 'explicit'.
8579 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8580 }
8581
clang_CXXField_isMutable(CXCursor C)8582 unsigned clang_CXXField_isMutable(CXCursor C) {
8583 if (!clang_isDeclaration(C.kind))
8584 return 0;
8585
8586 if (const auto D = cxcursor::getCursorDecl(C))
8587 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8588 return FD->isMutable() ? 1 : 0;
8589 return 0;
8590 }
8591
clang_CXXMethod_isPureVirtual(CXCursor C)8592 unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8593 if (!clang_isDeclaration(C.kind))
8594 return 0;
8595
8596 const Decl *D = cxcursor::getCursorDecl(C);
8597 const CXXMethodDecl *Method =
8598 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8599 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8600 }
8601
clang_CXXMethod_isConst(CXCursor C)8602 unsigned clang_CXXMethod_isConst(CXCursor C) {
8603 if (!clang_isDeclaration(C.kind))
8604 return 0;
8605
8606 const Decl *D = cxcursor::getCursorDecl(C);
8607 const CXXMethodDecl *Method =
8608 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8609 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
8610 }
8611
clang_CXXMethod_isDefaulted(CXCursor C)8612 unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8613 if (!clang_isDeclaration(C.kind))
8614 return 0;
8615
8616 const Decl *D = cxcursor::getCursorDecl(C);
8617 const CXXMethodDecl *Method =
8618 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8619 return (Method && Method->isDefaulted()) ? 1 : 0;
8620 }
8621
clang_CXXMethod_isStatic(CXCursor C)8622 unsigned clang_CXXMethod_isStatic(CXCursor C) {
8623 if (!clang_isDeclaration(C.kind))
8624 return 0;
8625
8626 const Decl *D = cxcursor::getCursorDecl(C);
8627 const CXXMethodDecl *Method =
8628 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8629 return (Method && Method->isStatic()) ? 1 : 0;
8630 }
8631
clang_CXXMethod_isVirtual(CXCursor C)8632 unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8633 if (!clang_isDeclaration(C.kind))
8634 return 0;
8635
8636 const Decl *D = cxcursor::getCursorDecl(C);
8637 const CXXMethodDecl *Method =
8638 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8639 return (Method && Method->isVirtual()) ? 1 : 0;
8640 }
8641
clang_CXXRecord_isAbstract(CXCursor C)8642 unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8643 if (!clang_isDeclaration(C.kind))
8644 return 0;
8645
8646 const auto *D = cxcursor::getCursorDecl(C);
8647 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8648 if (RD)
8649 RD = RD->getDefinition();
8650 return (RD && RD->isAbstract()) ? 1 : 0;
8651 }
8652
clang_EnumDecl_isScoped(CXCursor C)8653 unsigned clang_EnumDecl_isScoped(CXCursor C) {
8654 if (!clang_isDeclaration(C.kind))
8655 return 0;
8656
8657 const Decl *D = cxcursor::getCursorDecl(C);
8658 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8659 return (Enum && Enum->isScoped()) ? 1 : 0;
8660 }
8661
8662 //===----------------------------------------------------------------------===//
8663 // Attribute introspection.
8664 //===----------------------------------------------------------------------===//
8665
clang_getIBOutletCollectionType(CXCursor C)8666 CXType clang_getIBOutletCollectionType(CXCursor C) {
8667 if (C.kind != CXCursor_IBOutletCollectionAttr)
8668 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
8669
8670 const IBOutletCollectionAttr *A =
8671 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8672
8673 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
8674 }
8675
8676 //===----------------------------------------------------------------------===//
8677 // Inspecting memory usage.
8678 //===----------------------------------------------------------------------===//
8679
8680 typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8681
createCXTUResourceUsageEntry(MemUsageEntries & entries,enum CXTUResourceUsageKind k,unsigned long amount)8682 static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
8683 enum CXTUResourceUsageKind k,
8684 unsigned long amount) {
8685 CXTUResourceUsageEntry entry = {k, amount};
8686 entries.push_back(entry);
8687 }
8688
clang_getTUResourceUsageName(CXTUResourceUsageKind kind)8689 const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8690 const char *str = "";
8691 switch (kind) {
8692 case CXTUResourceUsage_AST:
8693 str = "ASTContext: expressions, declarations, and types";
8694 break;
8695 case CXTUResourceUsage_Identifiers:
8696 str = "ASTContext: identifiers";
8697 break;
8698 case CXTUResourceUsage_Selectors:
8699 str = "ASTContext: selectors";
8700 break;
8701 case CXTUResourceUsage_GlobalCompletionResults:
8702 str = "Code completion: cached global results";
8703 break;
8704 case CXTUResourceUsage_SourceManagerContentCache:
8705 str = "SourceManager: content cache allocator";
8706 break;
8707 case CXTUResourceUsage_AST_SideTables:
8708 str = "ASTContext: side tables";
8709 break;
8710 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8711 str = "SourceManager: malloc'ed memory buffers";
8712 break;
8713 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8714 str = "SourceManager: mmap'ed memory buffers";
8715 break;
8716 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8717 str = "ExternalASTSource: malloc'ed memory buffers";
8718 break;
8719 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8720 str = "ExternalASTSource: mmap'ed memory buffers";
8721 break;
8722 case CXTUResourceUsage_Preprocessor:
8723 str = "Preprocessor: malloc'ed memory";
8724 break;
8725 case CXTUResourceUsage_PreprocessingRecord:
8726 str = "Preprocessor: PreprocessingRecord";
8727 break;
8728 case CXTUResourceUsage_SourceManager_DataStructures:
8729 str = "SourceManager: data structures and tables";
8730 break;
8731 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8732 str = "Preprocessor: header search tables";
8733 break;
8734 }
8735 return str;
8736 }
8737
clang_getCXTUResourceUsage(CXTranslationUnit TU)8738 CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
8739 if (isNotUsableTU(TU)) {
8740 LOG_BAD_TU(TU);
8741 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
8742 return usage;
8743 }
8744
8745 ASTUnit *astUnit = cxtu::getASTUnit(TU);
8746 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
8747 ASTContext &astContext = astUnit->getASTContext();
8748
8749 // How much memory is used by AST nodes and types?
8750 createCXTUResourceUsageEntry(
8751 *entries, CXTUResourceUsage_AST,
8752 (unsigned long)astContext.getASTAllocatedMemory());
8753
8754 // How much memory is used by identifiers?
8755 createCXTUResourceUsageEntry(
8756 *entries, CXTUResourceUsage_Identifiers,
8757 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
8758
8759 // How much memory is used for selectors?
8760 createCXTUResourceUsageEntry(
8761 *entries, CXTUResourceUsage_Selectors,
8762 (unsigned long)astContext.Selectors.getTotalMemory());
8763
8764 // How much memory is used by ASTContext's side tables?
8765 createCXTUResourceUsageEntry(
8766 *entries, CXTUResourceUsage_AST_SideTables,
8767 (unsigned long)astContext.getSideTableAllocatedMemory());
8768
8769 // How much memory is used for caching global code completion results?
8770 unsigned long completionBytes = 0;
8771 if (GlobalCodeCompletionAllocator *completionAllocator =
8772 astUnit->getCachedCompletionAllocator().get()) {
8773 completionBytes = completionAllocator->getTotalMemory();
8774 }
8775 createCXTUResourceUsageEntry(
8776 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8777
8778 // How much memory is being used by SourceManager's content cache?
8779 createCXTUResourceUsageEntry(
8780 *entries, CXTUResourceUsage_SourceManagerContentCache,
8781 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8782
8783 // How much memory is being used by the MemoryBuffer's in SourceManager?
8784 const SourceManager::MemoryBufferSizes &srcBufs =
8785 astUnit->getSourceManager().getMemoryBufferSizes();
8786
8787 createCXTUResourceUsageEntry(*entries,
8788 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
8789 (unsigned long)srcBufs.malloc_bytes);
8790 createCXTUResourceUsageEntry(*entries,
8791 CXTUResourceUsage_SourceManager_Membuffer_MMap,
8792 (unsigned long)srcBufs.mmap_bytes);
8793 createCXTUResourceUsageEntry(
8794 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8795 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8796
8797 // How much memory is being used by the ExternalASTSource?
8798 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8799 const ExternalASTSource::MemoryBufferSizes &sizes =
8800 esrc->getMemoryBufferSizes();
8801
8802 createCXTUResourceUsageEntry(
8803 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8804 (unsigned long)sizes.malloc_bytes);
8805 createCXTUResourceUsageEntry(
8806 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8807 (unsigned long)sizes.mmap_bytes);
8808 }
8809
8810 // How much memory is being used by the Preprocessor?
8811 Preprocessor &pp = astUnit->getPreprocessor();
8812 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
8813 pp.getTotalMemory());
8814
8815 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8816 createCXTUResourceUsageEntry(*entries,
8817 CXTUResourceUsage_PreprocessingRecord,
8818 pRec->getTotalMemory());
8819 }
8820
8821 createCXTUResourceUsageEntry(*entries,
8822 CXTUResourceUsage_Preprocessor_HeaderSearch,
8823 pp.getHeaderSearchInfo().getTotalMemory());
8824
8825 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8826 !entries->empty() ? &(*entries)[0] : nullptr};
8827 (void)entries.release();
8828 return usage;
8829 }
8830
clang_disposeCXTUResourceUsage(CXTUResourceUsage usage)8831 void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8832 if (usage.data)
8833 delete (MemUsageEntries *)usage.data;
8834 }
8835
clang_getSkippedRanges(CXTranslationUnit TU,CXFile file)8836 CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8837 CXSourceRangeList *skipped = new CXSourceRangeList;
8838 skipped->count = 0;
8839 skipped->ranges = nullptr;
8840
8841 if (isNotUsableTU(TU)) {
8842 LOG_BAD_TU(TU);
8843 return skipped;
8844 }
8845
8846 if (!file)
8847 return skipped;
8848
8849 ASTUnit *astUnit = cxtu::getASTUnit(TU);
8850 PreprocessingRecord *ppRec =
8851 astUnit->getPreprocessor().getPreprocessingRecord();
8852 if (!ppRec)
8853 return skipped;
8854
8855 ASTContext &Ctx = astUnit->getASTContext();
8856 SourceManager &sm = Ctx.getSourceManager();
8857 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8858 FileID wantedFileID = sm.translateFile(fileEntry);
8859 bool isMainFile = wantedFileID == sm.getMainFileID();
8860
8861 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8862 std::vector<SourceRange> wantedRanges;
8863 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8864 ei = SkippedRanges.end();
8865 i != ei; ++i) {
8866 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8867 sm.getFileID(i->getEnd()) == wantedFileID)
8868 wantedRanges.push_back(*i);
8869 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8870 astUnit->isInPreambleFileID(i->getEnd())))
8871 wantedRanges.push_back(*i);
8872 }
8873
8874 skipped->count = wantedRanges.size();
8875 skipped->ranges = new CXSourceRange[skipped->count];
8876 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8877 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8878
8879 return skipped;
8880 }
8881
clang_getAllSkippedRanges(CXTranslationUnit TU)8882 CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8883 CXSourceRangeList *skipped = new CXSourceRangeList;
8884 skipped->count = 0;
8885 skipped->ranges = nullptr;
8886
8887 if (isNotUsableTU(TU)) {
8888 LOG_BAD_TU(TU);
8889 return skipped;
8890 }
8891
8892 ASTUnit *astUnit = cxtu::getASTUnit(TU);
8893 PreprocessingRecord *ppRec =
8894 astUnit->getPreprocessor().getPreprocessingRecord();
8895 if (!ppRec)
8896 return skipped;
8897
8898 ASTContext &Ctx = astUnit->getASTContext();
8899
8900 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8901
8902 skipped->count = SkippedRanges.size();
8903 skipped->ranges = new CXSourceRange[skipped->count];
8904 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8905 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8906
8907 return skipped;
8908 }
8909
clang_disposeSourceRangeList(CXSourceRangeList * ranges)8910 void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8911 if (ranges) {
8912 delete[] ranges->ranges;
8913 delete ranges;
8914 }
8915 }
8916
PrintLibclangResourceUsage(CXTranslationUnit TU)8917 void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8918 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8919 for (unsigned I = 0; I != Usage.numEntries; ++I)
8920 fprintf(stderr, " %s: %lu\n",
8921 clang_getTUResourceUsageName(Usage.entries[I].kind),
8922 Usage.entries[I].amount);
8923
8924 clang_disposeCXTUResourceUsage(Usage);
8925 }
8926
clang_Cursor_getVarDeclInitializer(CXCursor cursor)8927 CXCursor clang_Cursor_getVarDeclInitializer(CXCursor cursor) {
8928 const Decl *const D = getCursorDecl(cursor);
8929 if (!D)
8930 return clang_getNullCursor();
8931 const auto *const VD = dyn_cast<VarDecl>(D);
8932 if (!VD)
8933 return clang_getNullCursor();
8934 const Expr *const Init = VD->getInit();
8935 if (!Init)
8936 return clang_getNullCursor();
8937
8938 return cxcursor::MakeCXCursor(Init, VD, cxcursor::getCursorTU(cursor));
8939 }
8940
clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor)8941 int clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor) {
8942 const Decl *const D = getCursorDecl(cursor);
8943 if (!D)
8944 return -1;
8945 const auto *const VD = dyn_cast<VarDecl>(D);
8946 if (!VD)
8947 return -1;
8948
8949 return VD->hasGlobalStorage();
8950 }
8951
clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor)8952 int clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor) {
8953 const Decl *const D = getCursorDecl(cursor);
8954 if (!D)
8955 return -1;
8956 const auto *const VD = dyn_cast<VarDecl>(D);
8957 if (!VD)
8958 return -1;
8959
8960 return VD->hasExternalStorage();
8961 }
8962
8963 //===----------------------------------------------------------------------===//
8964 // Misc. utility functions.
8965 //===----------------------------------------------------------------------===//
8966
8967 /// Default to using our desired 8 MB stack size on "safety" threads.
8968 static unsigned SafetyStackThreadSize = DesiredStackSize;
8969
8970 namespace clang {
8971
RunSafely(llvm::CrashRecoveryContext & CRC,llvm::function_ref<void ()> Fn,unsigned Size)8972 bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
8973 unsigned Size) {
8974 if (!Size)
8975 Size = GetSafetyThreadStackSize();
8976 if (Size && !getenv("LIBCLANG_NOTHREADS"))
8977 return CRC.RunSafelyOnThread(Fn, Size);
8978 return CRC.RunSafely(Fn);
8979 }
8980
GetSafetyThreadStackSize()8981 unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
8982
SetSafetyThreadStackSize(unsigned Value)8983 void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
8984
8985 } // namespace clang
8986
setThreadBackgroundPriority()8987 void clang::setThreadBackgroundPriority() {
8988 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8989 return;
8990
8991 #if LLVM_ENABLE_THREADS
8992 llvm::set_thread_priority(llvm::ThreadPriority::Background);
8993 #endif
8994 }
8995
printDiagsToStderr(ASTUnit * Unit)8996 void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8997 if (!Unit)
8998 return;
8999
9000 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
9001 DEnd = Unit->stored_diag_end();
9002 D != DEnd; ++D) {
9003 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
9004 CXString Msg =
9005 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
9006 fprintf(stderr, "%s\n", clang_getCString(Msg));
9007 clang_disposeString(Msg);
9008 }
9009 #ifdef _WIN32
9010 // On Windows, force a flush, since there may be multiple copies of
9011 // stderr and stdout in the file system, all with different buffers
9012 // but writing to the same device.
9013 fflush(stderr);
9014 #endif
9015 }
9016
getMacroInfo(const IdentifierInfo & II,SourceLocation MacroDefLoc,CXTranslationUnit TU)9017 MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
9018 SourceLocation MacroDefLoc,
9019 CXTranslationUnit TU) {
9020 if (MacroDefLoc.isInvalid() || !TU)
9021 return nullptr;
9022 if (!II.hadMacroDefinition())
9023 return nullptr;
9024
9025 ASTUnit *Unit = cxtu::getASTUnit(TU);
9026 Preprocessor &PP = Unit->getPreprocessor();
9027 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
9028 if (MD) {
9029 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
9030 Def = Def.getPreviousDefinition()) {
9031 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
9032 return Def.getMacroInfo();
9033 }
9034 }
9035
9036 return nullptr;
9037 }
9038
getMacroInfo(const MacroDefinitionRecord * MacroDef,CXTranslationUnit TU)9039 const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
9040 CXTranslationUnit TU) {
9041 if (!MacroDef || !TU)
9042 return nullptr;
9043 const IdentifierInfo *II = MacroDef->getName();
9044 if (!II)
9045 return nullptr;
9046
9047 return getMacroInfo(*II, MacroDef->getLocation(), TU);
9048 }
9049
9050 MacroDefinitionRecord *
checkForMacroInMacroDefinition(const MacroInfo * MI,const Token & Tok,CXTranslationUnit TU)9051 cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
9052 CXTranslationUnit TU) {
9053 if (!MI || !TU)
9054 return nullptr;
9055 if (Tok.isNot(tok::raw_identifier))
9056 return nullptr;
9057
9058 if (MI->getNumTokens() == 0)
9059 return nullptr;
9060 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
9061 MI->getDefinitionEndLoc());
9062 ASTUnit *Unit = cxtu::getASTUnit(TU);
9063
9064 // Check that the token is inside the definition and not its argument list.
9065 SourceManager &SM = Unit->getSourceManager();
9066 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
9067 return nullptr;
9068 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
9069 return nullptr;
9070
9071 Preprocessor &PP = Unit->getPreprocessor();
9072 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
9073 if (!PPRec)
9074 return nullptr;
9075
9076 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
9077 if (!II.hadMacroDefinition())
9078 return nullptr;
9079
9080 // Check that the identifier is not one of the macro arguments.
9081 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
9082 return nullptr;
9083
9084 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
9085 if (!InnerMD)
9086 return nullptr;
9087
9088 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
9089 }
9090
9091 MacroDefinitionRecord *
checkForMacroInMacroDefinition(const MacroInfo * MI,SourceLocation Loc,CXTranslationUnit TU)9092 cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
9093 CXTranslationUnit TU) {
9094 if (Loc.isInvalid() || !MI || !TU)
9095 return nullptr;
9096
9097 if (MI->getNumTokens() == 0)
9098 return nullptr;
9099 ASTUnit *Unit = cxtu::getASTUnit(TU);
9100 Preprocessor &PP = Unit->getPreprocessor();
9101 if (!PP.getPreprocessingRecord())
9102 return nullptr;
9103 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
9104 Token Tok;
9105 if (PP.getRawToken(Loc, Tok))
9106 return nullptr;
9107
9108 return checkForMacroInMacroDefinition(MI, Tok, TU);
9109 }
9110
clang_getClangVersion()9111 CXString clang_getClangVersion() {
9112 return cxstring::createDup(getClangFullVersion());
9113 }
9114
operator <<(CXTranslationUnit TU)9115 Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
9116 if (TU) {
9117 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
9118 LogOS << '<' << Unit->getMainFileName() << '>';
9119 if (Unit->isMainFileAST())
9120 LogOS << " (" << Unit->getASTFileName() << ')';
9121 return *this;
9122 }
9123 } else {
9124 LogOS << "<NULL TU>";
9125 }
9126 return *this;
9127 }
9128
operator <<(const FileEntry * FE)9129 Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
9130 *this << FE->getName();
9131 return *this;
9132 }
9133
operator <<(CXCursor cursor)9134 Logger &cxindex::Logger::operator<<(CXCursor cursor) {
9135 CXString cursorName = clang_getCursorDisplayName(cursor);
9136 *this << cursorName << "@" << clang_getCursorLocation(cursor);
9137 clang_disposeString(cursorName);
9138 return *this;
9139 }
9140
operator <<(CXSourceLocation Loc)9141 Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
9142 CXFile File;
9143 unsigned Line, Column;
9144 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
9145 CXString FileName = clang_getFileName(File);
9146 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
9147 clang_disposeString(FileName);
9148 return *this;
9149 }
9150
operator <<(CXSourceRange range)9151 Logger &cxindex::Logger::operator<<(CXSourceRange range) {
9152 CXSourceLocation BLoc = clang_getRangeStart(range);
9153 CXSourceLocation ELoc = clang_getRangeEnd(range);
9154
9155 CXFile BFile;
9156 unsigned BLine, BColumn;
9157 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
9158
9159 CXFile EFile;
9160 unsigned ELine, EColumn;
9161 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
9162
9163 CXString BFileName = clang_getFileName(BFile);
9164 if (BFile == EFile) {
9165 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
9166 BLine, BColumn, ELine, EColumn);
9167 } else {
9168 CXString EFileName = clang_getFileName(EFile);
9169 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9170 BColumn)
9171 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9172 EColumn);
9173 clang_disposeString(EFileName);
9174 }
9175 clang_disposeString(BFileName);
9176 return *this;
9177 }
9178
operator <<(CXString Str)9179 Logger &cxindex::Logger::operator<<(CXString Str) {
9180 *this << clang_getCString(Str);
9181 return *this;
9182 }
9183
operator <<(const llvm::format_object_base & Fmt)9184 Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9185 LogOS << Fmt;
9186 return *this;
9187 }
9188
9189 static llvm::ManagedStatic<std::mutex> LoggingMutex;
9190
~Logger()9191 cxindex::Logger::~Logger() {
9192 std::lock_guard<std::mutex> L(*LoggingMutex);
9193
9194 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9195
9196 raw_ostream &OS = llvm::errs();
9197 OS << "[libclang:" << Name << ':';
9198
9199 #ifdef USE_DARWIN_THREADS
9200 // TODO: Portability.
9201 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9202 OS << tid << ':';
9203 #endif
9204
9205 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9206 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
9207 OS << Msg << '\n';
9208
9209 if (Trace) {
9210 llvm::sys::PrintStackTrace(OS);
9211 OS << "--------------------------------------------------\n";
9212 }
9213 }
9214