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