1f4a2713aSLionel Sambuc //===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the main API hooks in the Clang-C Source Indexing
11f4a2713aSLionel Sambuc // library.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc
15f4a2713aSLionel Sambuc #include "CIndexer.h"
16f4a2713aSLionel Sambuc #include "CIndexDiagnostic.h"
17f4a2713aSLionel Sambuc #include "CLog.h"
18f4a2713aSLionel Sambuc #include "CXCursor.h"
19f4a2713aSLionel Sambuc #include "CXSourceLocation.h"
20f4a2713aSLionel Sambuc #include "CXString.h"
21f4a2713aSLionel Sambuc #include "CXTranslationUnit.h"
22f4a2713aSLionel Sambuc #include "CXType.h"
23f4a2713aSLionel Sambuc #include "CursorVisitor.h"
24f4a2713aSLionel Sambuc #include "clang/AST/Attr.h"
25*0a6a1f1dSLionel Sambuc #include "clang/AST/Mangle.h"
26f4a2713aSLionel Sambuc #include "clang/AST/StmtVisitor.h"
27f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h"
28*0a6a1f1dSLionel Sambuc #include "clang/Basic/DiagnosticCategories.h"
29*0a6a1f1dSLionel Sambuc #include "clang/Basic/DiagnosticIDs.h"
30*0a6a1f1dSLionel Sambuc #include "clang/Basic/TargetInfo.h"
31f4a2713aSLionel Sambuc #include "clang/Basic/Version.h"
32f4a2713aSLionel Sambuc #include "clang/Frontend/ASTUnit.h"
33f4a2713aSLionel Sambuc #include "clang/Frontend/CompilerInstance.h"
34f4a2713aSLionel Sambuc #include "clang/Frontend/FrontendDiagnostic.h"
35f4a2713aSLionel Sambuc #include "clang/Index/CommentToXML.h"
36f4a2713aSLionel Sambuc #include "clang/Lex/HeaderSearch.h"
37f4a2713aSLionel Sambuc #include "clang/Lex/Lexer.h"
38f4a2713aSLionel Sambuc #include "clang/Lex/PreprocessingRecord.h"
39f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
40*0a6a1f1dSLionel Sambuc #include "clang/Serialization/SerializationDiagnostic.h"
41f4a2713aSLionel Sambuc #include "llvm/ADT/Optional.h"
42f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
43f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
44*0a6a1f1dSLionel Sambuc #include "llvm/Config/llvm-config.h"
45*0a6a1f1dSLionel Sambuc #include "llvm/IR/DataLayout.h"
46*0a6a1f1dSLionel Sambuc #include "llvm/IR/Mangler.h"
47f4a2713aSLionel Sambuc #include "llvm/Support/Compiler.h"
48f4a2713aSLionel Sambuc #include "llvm/Support/CrashRecoveryContext.h"
49f4a2713aSLionel Sambuc #include "llvm/Support/Format.h"
50*0a6a1f1dSLionel Sambuc #include "llvm/Support/ManagedStatic.h"
51f4a2713aSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
52f4a2713aSLionel Sambuc #include "llvm/Support/Mutex.h"
53f4a2713aSLionel Sambuc #include "llvm/Support/Program.h"
54f4a2713aSLionel Sambuc #include "llvm/Support/SaveAndRestore.h"
55f4a2713aSLionel Sambuc #include "llvm/Support/Signals.h"
56f4a2713aSLionel Sambuc #include "llvm/Support/Threading.h"
57f4a2713aSLionel Sambuc #include "llvm/Support/Timer.h"
58f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
59f4a2713aSLionel Sambuc
60*0a6a1f1dSLionel Sambuc #if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61*0a6a1f1dSLionel Sambuc #define USE_DARWIN_THREADS
62*0a6a1f1dSLionel Sambuc #endif
63*0a6a1f1dSLionel Sambuc
64*0a6a1f1dSLionel Sambuc #ifdef USE_DARWIN_THREADS
65f4a2713aSLionel Sambuc #include <pthread.h>
66f4a2713aSLionel Sambuc #endif
67f4a2713aSLionel Sambuc
68f4a2713aSLionel Sambuc using namespace clang;
69f4a2713aSLionel Sambuc using namespace clang::cxcursor;
70f4a2713aSLionel Sambuc using namespace clang::cxtu;
71f4a2713aSLionel Sambuc using namespace clang::cxindex;
72f4a2713aSLionel Sambuc
MakeCXTranslationUnit(CIndexer * CIdx,ASTUnit * AU)73f4a2713aSLionel Sambuc CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74f4a2713aSLionel Sambuc if (!AU)
75*0a6a1f1dSLionel Sambuc return nullptr;
76*0a6a1f1dSLionel Sambuc assert(CIdx);
77f4a2713aSLionel Sambuc CXTranslationUnit D = new CXTranslationUnitImpl();
78f4a2713aSLionel Sambuc D->CIdx = CIdx;
79f4a2713aSLionel Sambuc D->TheASTUnit = AU;
80f4a2713aSLionel Sambuc D->StringPool = new cxstring::CXStringPool();
81*0a6a1f1dSLionel Sambuc D->Diagnostics = nullptr;
82f4a2713aSLionel Sambuc D->OverridenCursorsPool = createOverridenCXCursorsPool();
83*0a6a1f1dSLionel Sambuc D->CommentToXML = nullptr;
84f4a2713aSLionel Sambuc return D;
85f4a2713aSLionel Sambuc }
86f4a2713aSLionel Sambuc
isASTReadError(ASTUnit * AU)87*0a6a1f1dSLionel Sambuc bool cxtu::isASTReadError(ASTUnit *AU) {
88*0a6a1f1dSLionel Sambuc for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89*0a6a1f1dSLionel Sambuc DEnd = AU->stored_diag_end();
90*0a6a1f1dSLionel Sambuc D != DEnd; ++D) {
91*0a6a1f1dSLionel Sambuc if (D->getLevel() >= DiagnosticsEngine::Error &&
92*0a6a1f1dSLionel Sambuc DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93*0a6a1f1dSLionel Sambuc diag::DiagCat_AST_Deserialization_Issue)
94*0a6a1f1dSLionel Sambuc return true;
95*0a6a1f1dSLionel Sambuc }
96*0a6a1f1dSLionel Sambuc return false;
97*0a6a1f1dSLionel Sambuc }
98*0a6a1f1dSLionel Sambuc
~CXTUOwner()99f4a2713aSLionel Sambuc cxtu::CXTUOwner::~CXTUOwner() {
100f4a2713aSLionel Sambuc if (TU)
101f4a2713aSLionel Sambuc clang_disposeTranslationUnit(TU);
102f4a2713aSLionel Sambuc }
103f4a2713aSLionel Sambuc
104f4a2713aSLionel Sambuc /// \brief Compare two source ranges to determine their relative position in
105f4a2713aSLionel Sambuc /// the translation unit.
RangeCompare(SourceManager & SM,SourceRange R1,SourceRange R2)106f4a2713aSLionel Sambuc static RangeComparisonResult RangeCompare(SourceManager &SM,
107f4a2713aSLionel Sambuc SourceRange R1,
108f4a2713aSLionel Sambuc SourceRange R2) {
109f4a2713aSLionel Sambuc assert(R1.isValid() && "First range is invalid?");
110f4a2713aSLionel Sambuc assert(R2.isValid() && "Second range is invalid?");
111f4a2713aSLionel Sambuc if (R1.getEnd() != R2.getBegin() &&
112f4a2713aSLionel Sambuc SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113f4a2713aSLionel Sambuc return RangeBefore;
114f4a2713aSLionel Sambuc if (R2.getEnd() != R1.getBegin() &&
115f4a2713aSLionel Sambuc SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116f4a2713aSLionel Sambuc return RangeAfter;
117f4a2713aSLionel Sambuc return RangeOverlap;
118f4a2713aSLionel Sambuc }
119f4a2713aSLionel Sambuc
120f4a2713aSLionel Sambuc /// \brief Determine if a source location falls within, before, or after a
121f4a2713aSLionel Sambuc /// a given source range.
LocationCompare(SourceManager & SM,SourceLocation L,SourceRange R)122f4a2713aSLionel Sambuc static RangeComparisonResult LocationCompare(SourceManager &SM,
123f4a2713aSLionel Sambuc SourceLocation L, SourceRange R) {
124f4a2713aSLionel Sambuc assert(R.isValid() && "First range is invalid?");
125f4a2713aSLionel Sambuc assert(L.isValid() && "Second range is invalid?");
126f4a2713aSLionel Sambuc if (L == R.getBegin() || L == R.getEnd())
127f4a2713aSLionel Sambuc return RangeOverlap;
128f4a2713aSLionel Sambuc if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129f4a2713aSLionel Sambuc return RangeBefore;
130f4a2713aSLionel Sambuc if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131f4a2713aSLionel Sambuc return RangeAfter;
132f4a2713aSLionel Sambuc return RangeOverlap;
133f4a2713aSLionel Sambuc }
134f4a2713aSLionel Sambuc
135f4a2713aSLionel Sambuc /// \brief Translate a Clang source range into a CIndex source range.
136f4a2713aSLionel Sambuc ///
137f4a2713aSLionel Sambuc /// Clang internally represents ranges where the end location points to the
138f4a2713aSLionel Sambuc /// start of the token at the end. However, for external clients it is more
139f4a2713aSLionel Sambuc /// useful to have a CXSourceRange be a proper half-open interval. This routine
140f4a2713aSLionel Sambuc /// does the appropriate translation.
translateSourceRange(const SourceManager & SM,const LangOptions & LangOpts,const CharSourceRange & R)141f4a2713aSLionel Sambuc CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142f4a2713aSLionel Sambuc const LangOptions &LangOpts,
143f4a2713aSLionel Sambuc const CharSourceRange &R) {
144f4a2713aSLionel Sambuc // We want the last character in this location, so we will adjust the
145f4a2713aSLionel Sambuc // location accordingly.
146f4a2713aSLionel Sambuc SourceLocation EndLoc = R.getEnd();
147f4a2713aSLionel Sambuc if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148f4a2713aSLionel Sambuc EndLoc = SM.getExpansionRange(EndLoc).second;
149f4a2713aSLionel Sambuc if (R.isTokenRange() && !EndLoc.isInvalid()) {
150f4a2713aSLionel Sambuc unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151f4a2713aSLionel Sambuc SM, LangOpts);
152f4a2713aSLionel Sambuc EndLoc = EndLoc.getLocWithOffset(Length);
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc
155f4a2713aSLionel Sambuc CXSourceRange Result = {
156f4a2713aSLionel Sambuc { &SM, &LangOpts },
157f4a2713aSLionel Sambuc R.getBegin().getRawEncoding(),
158f4a2713aSLionel Sambuc EndLoc.getRawEncoding()
159f4a2713aSLionel Sambuc };
160f4a2713aSLionel Sambuc return Result;
161f4a2713aSLionel Sambuc }
162f4a2713aSLionel Sambuc
163f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
164f4a2713aSLionel Sambuc // Cursor visitor.
165f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
166f4a2713aSLionel Sambuc
167f4a2713aSLionel Sambuc static SourceRange getRawCursorExtent(CXCursor C);
168f4a2713aSLionel Sambuc static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169f4a2713aSLionel Sambuc
170f4a2713aSLionel Sambuc
CompareRegionOfInterest(SourceRange R)171f4a2713aSLionel Sambuc RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172f4a2713aSLionel Sambuc return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173f4a2713aSLionel Sambuc }
174f4a2713aSLionel Sambuc
175f4a2713aSLionel Sambuc /// \brief Visit the given cursor and, if requested by the visitor,
176f4a2713aSLionel Sambuc /// its children.
177f4a2713aSLionel Sambuc ///
178f4a2713aSLionel Sambuc /// \param Cursor the cursor to visit.
179f4a2713aSLionel Sambuc ///
180f4a2713aSLionel Sambuc /// \param CheckedRegionOfInterest if true, then the caller already checked
181f4a2713aSLionel Sambuc /// that this cursor is within the region of interest.
182f4a2713aSLionel Sambuc ///
183f4a2713aSLionel Sambuc /// \returns true if the visitation should be aborted, false if it
184f4a2713aSLionel Sambuc /// should continue.
Visit(CXCursor Cursor,bool CheckedRegionOfInterest)185f4a2713aSLionel Sambuc bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186f4a2713aSLionel Sambuc if (clang_isInvalid(Cursor.kind))
187f4a2713aSLionel Sambuc return false;
188f4a2713aSLionel Sambuc
189f4a2713aSLionel Sambuc if (clang_isDeclaration(Cursor.kind)) {
190f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(Cursor);
191f4a2713aSLionel Sambuc if (!D) {
192f4a2713aSLionel Sambuc assert(0 && "Invalid declaration cursor");
193f4a2713aSLionel Sambuc return true; // abort.
194f4a2713aSLionel Sambuc }
195f4a2713aSLionel Sambuc
196f4a2713aSLionel Sambuc // Ignore implicit declarations, unless it's an objc method because
197f4a2713aSLionel Sambuc // currently we should report implicit methods for properties when indexing.
198f4a2713aSLionel Sambuc if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199f4a2713aSLionel Sambuc return false;
200f4a2713aSLionel Sambuc }
201f4a2713aSLionel Sambuc
202f4a2713aSLionel Sambuc // If we have a range of interest, and this cursor doesn't intersect with it,
203f4a2713aSLionel Sambuc // we're done.
204f4a2713aSLionel Sambuc if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205f4a2713aSLionel Sambuc SourceRange Range = getRawCursorExtent(Cursor);
206f4a2713aSLionel Sambuc if (Range.isInvalid() || CompareRegionOfInterest(Range))
207f4a2713aSLionel Sambuc return false;
208f4a2713aSLionel Sambuc }
209f4a2713aSLionel Sambuc
210f4a2713aSLionel Sambuc switch (Visitor(Cursor, Parent, ClientData)) {
211f4a2713aSLionel Sambuc case CXChildVisit_Break:
212f4a2713aSLionel Sambuc return true;
213f4a2713aSLionel Sambuc
214f4a2713aSLionel Sambuc case CXChildVisit_Continue:
215f4a2713aSLionel Sambuc return false;
216f4a2713aSLionel Sambuc
217f4a2713aSLionel Sambuc case CXChildVisit_Recurse: {
218f4a2713aSLionel Sambuc bool ret = VisitChildren(Cursor);
219f4a2713aSLionel Sambuc if (PostChildrenVisitor)
220f4a2713aSLionel Sambuc if (PostChildrenVisitor(Cursor, ClientData))
221f4a2713aSLionel Sambuc return true;
222f4a2713aSLionel Sambuc return ret;
223f4a2713aSLionel Sambuc }
224f4a2713aSLionel Sambuc }
225f4a2713aSLionel Sambuc
226f4a2713aSLionel Sambuc llvm_unreachable("Invalid CXChildVisitResult!");
227f4a2713aSLionel Sambuc }
228f4a2713aSLionel Sambuc
visitPreprocessedEntitiesInRange(SourceRange R,PreprocessingRecord & PPRec,CursorVisitor & Visitor)229f4a2713aSLionel Sambuc static bool visitPreprocessedEntitiesInRange(SourceRange R,
230f4a2713aSLionel Sambuc PreprocessingRecord &PPRec,
231f4a2713aSLionel Sambuc CursorVisitor &Visitor) {
232f4a2713aSLionel Sambuc SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233f4a2713aSLionel Sambuc FileID FID;
234f4a2713aSLionel Sambuc
235f4a2713aSLionel Sambuc if (!Visitor.shouldVisitIncludedEntities()) {
236f4a2713aSLionel Sambuc // If the begin/end of the range lie in the same FileID, do the optimization
237f4a2713aSLionel Sambuc // where we skip preprocessed entities that do not come from the same FileID.
238f4a2713aSLionel Sambuc FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239f4a2713aSLionel Sambuc if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240f4a2713aSLionel Sambuc FID = FileID();
241f4a2713aSLionel Sambuc }
242f4a2713aSLionel Sambuc
243f4a2713aSLionel Sambuc std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
244f4a2713aSLionel Sambuc Entities = PPRec.getPreprocessedEntitiesInRange(R);
245f4a2713aSLionel Sambuc return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
246f4a2713aSLionel Sambuc PPRec, FID);
247f4a2713aSLionel Sambuc }
248f4a2713aSLionel Sambuc
visitFileRegion()249f4a2713aSLionel Sambuc bool CursorVisitor::visitFileRegion() {
250f4a2713aSLionel Sambuc if (RegionOfInterest.isInvalid())
251f4a2713aSLionel Sambuc return false;
252f4a2713aSLionel Sambuc
253f4a2713aSLionel Sambuc ASTUnit *Unit = cxtu::getASTUnit(TU);
254f4a2713aSLionel Sambuc SourceManager &SM = Unit->getSourceManager();
255f4a2713aSLionel Sambuc
256f4a2713aSLionel Sambuc std::pair<FileID, unsigned>
257f4a2713aSLionel Sambuc Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258f4a2713aSLionel Sambuc End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259f4a2713aSLionel Sambuc
260f4a2713aSLionel Sambuc if (End.first != Begin.first) {
261f4a2713aSLionel Sambuc // If the end does not reside in the same file, try to recover by
262f4a2713aSLionel Sambuc // picking the end of the file of begin location.
263f4a2713aSLionel Sambuc End.first = Begin.first;
264f4a2713aSLionel Sambuc End.second = SM.getFileIDSize(Begin.first);
265f4a2713aSLionel Sambuc }
266f4a2713aSLionel Sambuc
267f4a2713aSLionel Sambuc assert(Begin.first == End.first);
268f4a2713aSLionel Sambuc if (Begin.second > End.second)
269f4a2713aSLionel Sambuc return false;
270f4a2713aSLionel Sambuc
271f4a2713aSLionel Sambuc FileID File = Begin.first;
272f4a2713aSLionel Sambuc unsigned Offset = Begin.second;
273f4a2713aSLionel Sambuc unsigned Length = End.second - Begin.second;
274f4a2713aSLionel Sambuc
275f4a2713aSLionel Sambuc if (!VisitDeclsOnly && !VisitPreprocessorLast)
276f4a2713aSLionel Sambuc if (visitPreprocessedEntitiesInRegion())
277f4a2713aSLionel Sambuc return true; // visitation break.
278f4a2713aSLionel Sambuc
279f4a2713aSLionel Sambuc if (visitDeclsFromFileRegion(File, Offset, Length))
280f4a2713aSLionel Sambuc return true; // visitation break.
281f4a2713aSLionel Sambuc
282f4a2713aSLionel Sambuc if (!VisitDeclsOnly && VisitPreprocessorLast)
283f4a2713aSLionel Sambuc return visitPreprocessedEntitiesInRegion();
284f4a2713aSLionel Sambuc
285f4a2713aSLionel Sambuc return false;
286f4a2713aSLionel Sambuc }
287f4a2713aSLionel Sambuc
isInLexicalContext(Decl * D,DeclContext * DC)288f4a2713aSLionel Sambuc static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289f4a2713aSLionel Sambuc if (!DC)
290f4a2713aSLionel Sambuc return false;
291f4a2713aSLionel Sambuc
292f4a2713aSLionel Sambuc for (DeclContext *DeclDC = D->getLexicalDeclContext();
293f4a2713aSLionel Sambuc DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294f4a2713aSLionel Sambuc if (DeclDC == DC)
295f4a2713aSLionel Sambuc return true;
296f4a2713aSLionel Sambuc }
297f4a2713aSLionel Sambuc return false;
298f4a2713aSLionel Sambuc }
299f4a2713aSLionel Sambuc
visitDeclsFromFileRegion(FileID File,unsigned Offset,unsigned Length)300f4a2713aSLionel Sambuc bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
301f4a2713aSLionel Sambuc unsigned Offset, unsigned Length) {
302f4a2713aSLionel Sambuc ASTUnit *Unit = cxtu::getASTUnit(TU);
303f4a2713aSLionel Sambuc SourceManager &SM = Unit->getSourceManager();
304f4a2713aSLionel Sambuc SourceRange Range = RegionOfInterest;
305f4a2713aSLionel Sambuc
306f4a2713aSLionel Sambuc SmallVector<Decl *, 16> Decls;
307f4a2713aSLionel Sambuc Unit->findFileRegionDecls(File, Offset, Length, Decls);
308f4a2713aSLionel Sambuc
309f4a2713aSLionel Sambuc // If we didn't find any file level decls for the file, try looking at the
310f4a2713aSLionel Sambuc // file that it was included from.
311f4a2713aSLionel Sambuc while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312f4a2713aSLionel Sambuc bool Invalid = false;
313f4a2713aSLionel Sambuc const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314f4a2713aSLionel Sambuc if (Invalid)
315f4a2713aSLionel Sambuc return false;
316f4a2713aSLionel Sambuc
317f4a2713aSLionel Sambuc SourceLocation Outer;
318f4a2713aSLionel Sambuc if (SLEntry.isFile())
319f4a2713aSLionel Sambuc Outer = SLEntry.getFile().getIncludeLoc();
320f4a2713aSLionel Sambuc else
321f4a2713aSLionel Sambuc Outer = SLEntry.getExpansion().getExpansionLocStart();
322f4a2713aSLionel Sambuc if (Outer.isInvalid())
323f4a2713aSLionel Sambuc return false;
324f4a2713aSLionel Sambuc
325*0a6a1f1dSLionel Sambuc std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
326f4a2713aSLionel Sambuc Length = 0;
327f4a2713aSLionel Sambuc Unit->findFileRegionDecls(File, Offset, Length, Decls);
328f4a2713aSLionel Sambuc }
329f4a2713aSLionel Sambuc
330f4a2713aSLionel Sambuc assert(!Decls.empty());
331f4a2713aSLionel Sambuc
332f4a2713aSLionel Sambuc bool VisitedAtLeastOnce = false;
333*0a6a1f1dSLionel Sambuc DeclContext *CurDC = nullptr;
334f4a2713aSLionel Sambuc SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335f4a2713aSLionel Sambuc for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
336f4a2713aSLionel Sambuc Decl *D = *DIt;
337f4a2713aSLionel Sambuc if (D->getSourceRange().isInvalid())
338f4a2713aSLionel Sambuc continue;
339f4a2713aSLionel Sambuc
340f4a2713aSLionel Sambuc if (isInLexicalContext(D, CurDC))
341f4a2713aSLionel Sambuc continue;
342f4a2713aSLionel Sambuc
343f4a2713aSLionel Sambuc CurDC = dyn_cast<DeclContext>(D);
344f4a2713aSLionel Sambuc
345f4a2713aSLionel Sambuc if (TagDecl *TD = dyn_cast<TagDecl>(D))
346f4a2713aSLionel Sambuc if (!TD->isFreeStanding())
347f4a2713aSLionel Sambuc continue;
348f4a2713aSLionel Sambuc
349f4a2713aSLionel Sambuc RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350f4a2713aSLionel Sambuc if (CompRes == RangeBefore)
351f4a2713aSLionel Sambuc continue;
352f4a2713aSLionel Sambuc if (CompRes == RangeAfter)
353f4a2713aSLionel Sambuc break;
354f4a2713aSLionel Sambuc
355f4a2713aSLionel Sambuc assert(CompRes == RangeOverlap);
356f4a2713aSLionel Sambuc VisitedAtLeastOnce = true;
357f4a2713aSLionel Sambuc
358f4a2713aSLionel Sambuc if (isa<ObjCContainerDecl>(D)) {
359f4a2713aSLionel Sambuc FileDI_current = &DIt;
360f4a2713aSLionel Sambuc FileDE_current = DE;
361f4a2713aSLionel Sambuc } else {
362*0a6a1f1dSLionel Sambuc FileDI_current = nullptr;
363f4a2713aSLionel Sambuc }
364f4a2713aSLionel Sambuc
365f4a2713aSLionel Sambuc if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
366f4a2713aSLionel Sambuc return true; // visitation break.
367f4a2713aSLionel Sambuc }
368f4a2713aSLionel Sambuc
369f4a2713aSLionel Sambuc if (VisitedAtLeastOnce)
370f4a2713aSLionel Sambuc return false;
371f4a2713aSLionel Sambuc
372f4a2713aSLionel Sambuc // No Decls overlapped with the range. Move up the lexical context until there
373f4a2713aSLionel Sambuc // is a context that contains the range or we reach the translation unit
374f4a2713aSLionel Sambuc // level.
375f4a2713aSLionel Sambuc DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376f4a2713aSLionel Sambuc : (*(DIt-1))->getLexicalDeclContext();
377f4a2713aSLionel Sambuc
378f4a2713aSLionel Sambuc while (DC && !DC->isTranslationUnit()) {
379f4a2713aSLionel Sambuc Decl *D = cast<Decl>(DC);
380f4a2713aSLionel Sambuc SourceRange CurDeclRange = D->getSourceRange();
381f4a2713aSLionel Sambuc if (CurDeclRange.isInvalid())
382f4a2713aSLionel Sambuc break;
383f4a2713aSLionel Sambuc
384f4a2713aSLionel Sambuc if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
385f4a2713aSLionel Sambuc if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386f4a2713aSLionel Sambuc return true; // visitation break.
387f4a2713aSLionel Sambuc }
388f4a2713aSLionel Sambuc
389f4a2713aSLionel Sambuc DC = D->getLexicalDeclContext();
390f4a2713aSLionel Sambuc }
391f4a2713aSLionel Sambuc
392f4a2713aSLionel Sambuc return false;
393f4a2713aSLionel Sambuc }
394f4a2713aSLionel Sambuc
visitPreprocessedEntitiesInRegion()395f4a2713aSLionel Sambuc bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396f4a2713aSLionel Sambuc if (!AU->getPreprocessor().getPreprocessingRecord())
397f4a2713aSLionel Sambuc return false;
398f4a2713aSLionel Sambuc
399f4a2713aSLionel Sambuc PreprocessingRecord &PPRec
400f4a2713aSLionel Sambuc = *AU->getPreprocessor().getPreprocessingRecord();
401f4a2713aSLionel Sambuc SourceManager &SM = AU->getSourceManager();
402f4a2713aSLionel Sambuc
403f4a2713aSLionel Sambuc if (RegionOfInterest.isValid()) {
404f4a2713aSLionel Sambuc SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405f4a2713aSLionel Sambuc SourceLocation B = MappedRange.getBegin();
406f4a2713aSLionel Sambuc SourceLocation E = MappedRange.getEnd();
407f4a2713aSLionel Sambuc
408f4a2713aSLionel Sambuc if (AU->isInPreambleFileID(B)) {
409f4a2713aSLionel Sambuc if (SM.isLoadedSourceLocation(E))
410f4a2713aSLionel Sambuc return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411f4a2713aSLionel Sambuc PPRec, *this);
412f4a2713aSLionel Sambuc
413f4a2713aSLionel Sambuc // Beginning of range lies in the preamble but it also extends beyond
414f4a2713aSLionel Sambuc // it into the main file. Split the range into 2 parts, one covering
415f4a2713aSLionel Sambuc // the preamble and another covering the main file. This allows subsequent
416f4a2713aSLionel Sambuc // calls to visitPreprocessedEntitiesInRange to accept a source range that
417f4a2713aSLionel Sambuc // lies in the same FileID, allowing it to skip preprocessed entities that
418f4a2713aSLionel Sambuc // do not come from the same FileID.
419f4a2713aSLionel Sambuc bool breaked =
420f4a2713aSLionel Sambuc visitPreprocessedEntitiesInRange(
421f4a2713aSLionel Sambuc SourceRange(B, AU->getEndOfPreambleFileID()),
422f4a2713aSLionel Sambuc PPRec, *this);
423f4a2713aSLionel Sambuc if (breaked) return true;
424f4a2713aSLionel Sambuc return visitPreprocessedEntitiesInRange(
425f4a2713aSLionel Sambuc SourceRange(AU->getStartOfMainFileID(), E),
426f4a2713aSLionel Sambuc PPRec, *this);
427f4a2713aSLionel Sambuc }
428f4a2713aSLionel Sambuc
429f4a2713aSLionel Sambuc return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430f4a2713aSLionel Sambuc }
431f4a2713aSLionel Sambuc
432f4a2713aSLionel Sambuc bool OnlyLocalDecls
433f4a2713aSLionel Sambuc = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434f4a2713aSLionel Sambuc
435f4a2713aSLionel Sambuc if (OnlyLocalDecls)
436f4a2713aSLionel Sambuc return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437f4a2713aSLionel Sambuc PPRec);
438f4a2713aSLionel Sambuc
439f4a2713aSLionel Sambuc return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440f4a2713aSLionel Sambuc }
441f4a2713aSLionel Sambuc
442f4a2713aSLionel Sambuc template<typename InputIterator>
visitPreprocessedEntities(InputIterator First,InputIterator Last,PreprocessingRecord & PPRec,FileID FID)443f4a2713aSLionel Sambuc bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444f4a2713aSLionel Sambuc InputIterator Last,
445f4a2713aSLionel Sambuc PreprocessingRecord &PPRec,
446f4a2713aSLionel Sambuc FileID FID) {
447f4a2713aSLionel Sambuc for (; First != Last; ++First) {
448f4a2713aSLionel Sambuc if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449f4a2713aSLionel Sambuc continue;
450f4a2713aSLionel Sambuc
451f4a2713aSLionel Sambuc PreprocessedEntity *PPE = *First;
452f4a2713aSLionel Sambuc if (!PPE)
453f4a2713aSLionel Sambuc continue;
454f4a2713aSLionel Sambuc
455f4a2713aSLionel Sambuc if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456f4a2713aSLionel Sambuc if (Visit(MakeMacroExpansionCursor(ME, TU)))
457f4a2713aSLionel Sambuc return true;
458f4a2713aSLionel Sambuc
459f4a2713aSLionel Sambuc continue;
460f4a2713aSLionel Sambuc }
461f4a2713aSLionel Sambuc
462f4a2713aSLionel Sambuc if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
463f4a2713aSLionel Sambuc if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464f4a2713aSLionel Sambuc return true;
465f4a2713aSLionel Sambuc
466f4a2713aSLionel Sambuc continue;
467f4a2713aSLionel Sambuc }
468f4a2713aSLionel Sambuc
469f4a2713aSLionel Sambuc if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470f4a2713aSLionel Sambuc if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471f4a2713aSLionel Sambuc return true;
472f4a2713aSLionel Sambuc
473f4a2713aSLionel Sambuc continue;
474f4a2713aSLionel Sambuc }
475f4a2713aSLionel Sambuc }
476f4a2713aSLionel Sambuc
477f4a2713aSLionel Sambuc return false;
478f4a2713aSLionel Sambuc }
479f4a2713aSLionel Sambuc
480f4a2713aSLionel Sambuc /// \brief Visit the children of the given cursor.
481f4a2713aSLionel Sambuc ///
482f4a2713aSLionel Sambuc /// \returns true if the visitation should be aborted, false if it
483f4a2713aSLionel Sambuc /// should continue.
VisitChildren(CXCursor Cursor)484f4a2713aSLionel Sambuc bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485f4a2713aSLionel Sambuc if (clang_isReference(Cursor.kind) &&
486f4a2713aSLionel Sambuc Cursor.kind != CXCursor_CXXBaseSpecifier) {
487f4a2713aSLionel Sambuc // By definition, references have no children.
488f4a2713aSLionel Sambuc return false;
489f4a2713aSLionel Sambuc }
490f4a2713aSLionel Sambuc
491f4a2713aSLionel Sambuc // Set the Parent field to Cursor, then back to its old value once we're
492f4a2713aSLionel Sambuc // done.
493f4a2713aSLionel Sambuc SetParentRAII SetParent(Parent, StmtParent, Cursor);
494f4a2713aSLionel Sambuc
495f4a2713aSLionel Sambuc if (clang_isDeclaration(Cursor.kind)) {
496f4a2713aSLionel Sambuc Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
497f4a2713aSLionel Sambuc if (!D)
498f4a2713aSLionel Sambuc return false;
499f4a2713aSLionel Sambuc
500f4a2713aSLionel Sambuc return VisitAttributes(D) || Visit(D);
501f4a2713aSLionel Sambuc }
502f4a2713aSLionel Sambuc
503f4a2713aSLionel Sambuc if (clang_isStatement(Cursor.kind)) {
504f4a2713aSLionel Sambuc if (const Stmt *S = getCursorStmt(Cursor))
505f4a2713aSLionel Sambuc return Visit(S);
506f4a2713aSLionel Sambuc
507f4a2713aSLionel Sambuc return false;
508f4a2713aSLionel Sambuc }
509f4a2713aSLionel Sambuc
510f4a2713aSLionel Sambuc if (clang_isExpression(Cursor.kind)) {
511f4a2713aSLionel Sambuc if (const Expr *E = getCursorExpr(Cursor))
512f4a2713aSLionel Sambuc return Visit(E);
513f4a2713aSLionel Sambuc
514f4a2713aSLionel Sambuc return false;
515f4a2713aSLionel Sambuc }
516f4a2713aSLionel Sambuc
517f4a2713aSLionel Sambuc if (clang_isTranslationUnit(Cursor.kind)) {
518f4a2713aSLionel Sambuc CXTranslationUnit TU = getCursorTU(Cursor);
519f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
520f4a2713aSLionel Sambuc
521f4a2713aSLionel Sambuc int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522f4a2713aSLionel Sambuc for (unsigned I = 0; I != 2; ++I) {
523f4a2713aSLionel Sambuc if (VisitOrder[I]) {
524f4a2713aSLionel Sambuc if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525f4a2713aSLionel Sambuc RegionOfInterest.isInvalid()) {
526f4a2713aSLionel Sambuc for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527f4a2713aSLionel Sambuc TLEnd = CXXUnit->top_level_end();
528f4a2713aSLionel Sambuc TL != TLEnd; ++TL) {
529f4a2713aSLionel Sambuc if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
530f4a2713aSLionel Sambuc return true;
531f4a2713aSLionel Sambuc }
532f4a2713aSLionel Sambuc } else if (VisitDeclContext(
533f4a2713aSLionel Sambuc CXXUnit->getASTContext().getTranslationUnitDecl()))
534f4a2713aSLionel Sambuc return true;
535f4a2713aSLionel Sambuc continue;
536f4a2713aSLionel Sambuc }
537f4a2713aSLionel Sambuc
538f4a2713aSLionel Sambuc // Walk the preprocessing record.
539f4a2713aSLionel Sambuc if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540f4a2713aSLionel Sambuc visitPreprocessedEntitiesInRegion();
541f4a2713aSLionel Sambuc }
542f4a2713aSLionel Sambuc
543f4a2713aSLionel Sambuc return false;
544f4a2713aSLionel Sambuc }
545f4a2713aSLionel Sambuc
546f4a2713aSLionel Sambuc if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
547f4a2713aSLionel Sambuc if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
548f4a2713aSLionel Sambuc if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549f4a2713aSLionel Sambuc return Visit(BaseTSInfo->getTypeLoc());
550f4a2713aSLionel Sambuc }
551f4a2713aSLionel Sambuc }
552f4a2713aSLionel Sambuc }
553f4a2713aSLionel Sambuc
554f4a2713aSLionel Sambuc if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
555f4a2713aSLionel Sambuc const IBOutletCollectionAttr *A =
556f4a2713aSLionel Sambuc cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
557f4a2713aSLionel Sambuc if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
558f4a2713aSLionel Sambuc return Visit(cxcursor::MakeCursorObjCClassRef(
559f4a2713aSLionel Sambuc ObjT->getInterface(),
560f4a2713aSLionel Sambuc A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
561f4a2713aSLionel Sambuc }
562f4a2713aSLionel Sambuc
563f4a2713aSLionel Sambuc // If pointing inside a macro definition, check if the token is an identifier
564f4a2713aSLionel Sambuc // that was ever defined as a macro. In such a case, create a "pseudo" macro
565f4a2713aSLionel Sambuc // expansion cursor for that token.
566f4a2713aSLionel Sambuc SourceLocation BeginLoc = RegionOfInterest.getBegin();
567f4a2713aSLionel Sambuc if (Cursor.kind == CXCursor_MacroDefinition &&
568f4a2713aSLionel Sambuc BeginLoc == RegionOfInterest.getEnd()) {
569f4a2713aSLionel Sambuc SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
570f4a2713aSLionel Sambuc const MacroInfo *MI =
571f4a2713aSLionel Sambuc getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
572f4a2713aSLionel Sambuc if (MacroDefinition *MacroDef =
573f4a2713aSLionel Sambuc checkForMacroInMacroDefinition(MI, Loc, TU))
574f4a2713aSLionel Sambuc return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575f4a2713aSLionel Sambuc }
576f4a2713aSLionel Sambuc
577f4a2713aSLionel Sambuc // Nothing to visit at the moment.
578f4a2713aSLionel Sambuc return false;
579f4a2713aSLionel Sambuc }
580f4a2713aSLionel Sambuc
VisitBlockDecl(BlockDecl * B)581f4a2713aSLionel Sambuc bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583f4a2713aSLionel Sambuc if (Visit(TSInfo->getTypeLoc()))
584f4a2713aSLionel Sambuc return true;
585f4a2713aSLionel Sambuc
586f4a2713aSLionel Sambuc if (Stmt *Body = B->getBody())
587f4a2713aSLionel Sambuc return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588f4a2713aSLionel Sambuc
589f4a2713aSLionel Sambuc return false;
590f4a2713aSLionel Sambuc }
591f4a2713aSLionel Sambuc
shouldVisitCursor(CXCursor Cursor)592f4a2713aSLionel Sambuc Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
593f4a2713aSLionel Sambuc if (RegionOfInterest.isValid()) {
594f4a2713aSLionel Sambuc SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595f4a2713aSLionel Sambuc if (Range.isInvalid())
596f4a2713aSLionel Sambuc return None;
597f4a2713aSLionel Sambuc
598f4a2713aSLionel Sambuc switch (CompareRegionOfInterest(Range)) {
599f4a2713aSLionel Sambuc case RangeBefore:
600f4a2713aSLionel Sambuc // This declaration comes before the region of interest; skip it.
601f4a2713aSLionel Sambuc return None;
602f4a2713aSLionel Sambuc
603f4a2713aSLionel Sambuc case RangeAfter:
604f4a2713aSLionel Sambuc // This declaration comes after the region of interest; we're done.
605f4a2713aSLionel Sambuc return false;
606f4a2713aSLionel Sambuc
607f4a2713aSLionel Sambuc case RangeOverlap:
608f4a2713aSLionel Sambuc // This declaration overlaps the region of interest; visit it.
609f4a2713aSLionel Sambuc break;
610f4a2713aSLionel Sambuc }
611f4a2713aSLionel Sambuc }
612f4a2713aSLionel Sambuc return true;
613f4a2713aSLionel Sambuc }
614f4a2713aSLionel Sambuc
VisitDeclContext(DeclContext * DC)615f4a2713aSLionel Sambuc bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616f4a2713aSLionel Sambuc DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617f4a2713aSLionel Sambuc
618f4a2713aSLionel Sambuc // FIXME: Eventually remove. This part of a hack to support proper
619f4a2713aSLionel Sambuc // iteration over all Decls contained lexically within an ObjC container.
620f4a2713aSLionel Sambuc SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621f4a2713aSLionel Sambuc SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622f4a2713aSLionel Sambuc
623f4a2713aSLionel Sambuc for ( ; I != E; ++I) {
624f4a2713aSLionel Sambuc Decl *D = *I;
625f4a2713aSLionel Sambuc if (D->getLexicalDeclContext() != DC)
626f4a2713aSLionel Sambuc continue;
627f4a2713aSLionel Sambuc CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628f4a2713aSLionel Sambuc
629f4a2713aSLionel Sambuc // Ignore synthesized ivars here, otherwise if we have something like:
630f4a2713aSLionel Sambuc // @synthesize prop = _prop;
631f4a2713aSLionel Sambuc // and '_prop' is not declared, we will encounter a '_prop' ivar before
632f4a2713aSLionel Sambuc // encountering the 'prop' synthesize declaration and we will think that
633f4a2713aSLionel Sambuc // we passed the region-of-interest.
634f4a2713aSLionel Sambuc if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635f4a2713aSLionel Sambuc if (ivarD->getSynthesize())
636f4a2713aSLionel Sambuc continue;
637f4a2713aSLionel Sambuc }
638f4a2713aSLionel Sambuc
639f4a2713aSLionel Sambuc // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640f4a2713aSLionel Sambuc // declarations is a mismatch with the compiler semantics.
641f4a2713aSLionel Sambuc if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642f4a2713aSLionel Sambuc ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643f4a2713aSLionel Sambuc if (!ID->isThisDeclarationADefinition())
644f4a2713aSLionel Sambuc Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645f4a2713aSLionel Sambuc
646f4a2713aSLionel Sambuc } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647f4a2713aSLionel Sambuc ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648f4a2713aSLionel Sambuc if (!PD->isThisDeclarationADefinition())
649f4a2713aSLionel Sambuc Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650f4a2713aSLionel Sambuc }
651f4a2713aSLionel Sambuc
652f4a2713aSLionel Sambuc const Optional<bool> &V = shouldVisitCursor(Cursor);
653f4a2713aSLionel Sambuc if (!V.hasValue())
654f4a2713aSLionel Sambuc continue;
655f4a2713aSLionel Sambuc if (!V.getValue())
656f4a2713aSLionel Sambuc return false;
657f4a2713aSLionel Sambuc if (Visit(Cursor, true))
658f4a2713aSLionel Sambuc return true;
659f4a2713aSLionel Sambuc }
660f4a2713aSLionel Sambuc return false;
661f4a2713aSLionel Sambuc }
662f4a2713aSLionel Sambuc
VisitTranslationUnitDecl(TranslationUnitDecl * D)663f4a2713aSLionel Sambuc bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664f4a2713aSLionel Sambuc llvm_unreachable("Translation units are visited directly by Visit()");
665f4a2713aSLionel Sambuc }
666f4a2713aSLionel Sambuc
VisitTypeAliasDecl(TypeAliasDecl * D)667f4a2713aSLionel Sambuc bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669f4a2713aSLionel Sambuc return Visit(TSInfo->getTypeLoc());
670f4a2713aSLionel Sambuc
671f4a2713aSLionel Sambuc return false;
672f4a2713aSLionel Sambuc }
673f4a2713aSLionel Sambuc
VisitTypedefDecl(TypedefDecl * D)674f4a2713aSLionel Sambuc bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676f4a2713aSLionel Sambuc return Visit(TSInfo->getTypeLoc());
677f4a2713aSLionel Sambuc
678f4a2713aSLionel Sambuc return false;
679f4a2713aSLionel Sambuc }
680f4a2713aSLionel Sambuc
VisitTagDecl(TagDecl * D)681f4a2713aSLionel Sambuc bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682f4a2713aSLionel Sambuc return VisitDeclContext(D);
683f4a2713aSLionel Sambuc }
684f4a2713aSLionel Sambuc
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)685f4a2713aSLionel Sambuc bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686f4a2713aSLionel Sambuc ClassTemplateSpecializationDecl *D) {
687f4a2713aSLionel Sambuc bool ShouldVisitBody = false;
688f4a2713aSLionel Sambuc switch (D->getSpecializationKind()) {
689f4a2713aSLionel Sambuc case TSK_Undeclared:
690f4a2713aSLionel Sambuc case TSK_ImplicitInstantiation:
691f4a2713aSLionel Sambuc // Nothing to visit
692f4a2713aSLionel Sambuc return false;
693f4a2713aSLionel Sambuc
694f4a2713aSLionel Sambuc case TSK_ExplicitInstantiationDeclaration:
695f4a2713aSLionel Sambuc case TSK_ExplicitInstantiationDefinition:
696f4a2713aSLionel Sambuc break;
697f4a2713aSLionel Sambuc
698f4a2713aSLionel Sambuc case TSK_ExplicitSpecialization:
699f4a2713aSLionel Sambuc ShouldVisitBody = true;
700f4a2713aSLionel Sambuc break;
701f4a2713aSLionel Sambuc }
702f4a2713aSLionel Sambuc
703f4a2713aSLionel Sambuc // Visit the template arguments used in the specialization.
704f4a2713aSLionel Sambuc if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705f4a2713aSLionel Sambuc TypeLoc TL = SpecType->getTypeLoc();
706f4a2713aSLionel Sambuc if (TemplateSpecializationTypeLoc TSTLoc =
707f4a2713aSLionel Sambuc TL.getAs<TemplateSpecializationTypeLoc>()) {
708f4a2713aSLionel Sambuc for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709f4a2713aSLionel Sambuc if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
710f4a2713aSLionel Sambuc return true;
711f4a2713aSLionel Sambuc }
712f4a2713aSLionel Sambuc }
713f4a2713aSLionel Sambuc
714f4a2713aSLionel Sambuc if (ShouldVisitBody && VisitCXXRecordDecl(D))
715f4a2713aSLionel Sambuc return true;
716f4a2713aSLionel Sambuc
717f4a2713aSLionel Sambuc return false;
718f4a2713aSLionel Sambuc }
719f4a2713aSLionel Sambuc
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)720f4a2713aSLionel Sambuc bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721f4a2713aSLionel Sambuc ClassTemplatePartialSpecializationDecl *D) {
722f4a2713aSLionel Sambuc // FIXME: Visit the "outer" template parameter lists on the TagDecl
723f4a2713aSLionel Sambuc // before visiting these template parameters.
724f4a2713aSLionel Sambuc if (VisitTemplateParameters(D->getTemplateParameters()))
725f4a2713aSLionel Sambuc return true;
726f4a2713aSLionel Sambuc
727f4a2713aSLionel Sambuc // Visit the partial specialization arguments.
728f4a2713aSLionel Sambuc const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729f4a2713aSLionel Sambuc const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730f4a2713aSLionel Sambuc for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
731f4a2713aSLionel Sambuc if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732f4a2713aSLionel Sambuc return true;
733f4a2713aSLionel Sambuc
734f4a2713aSLionel Sambuc return VisitCXXRecordDecl(D);
735f4a2713aSLionel Sambuc }
736f4a2713aSLionel Sambuc
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)737f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738f4a2713aSLionel Sambuc // Visit the default argument.
739f4a2713aSLionel Sambuc if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740f4a2713aSLionel Sambuc if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741f4a2713aSLionel Sambuc if (Visit(DefArg->getTypeLoc()))
742f4a2713aSLionel Sambuc return true;
743f4a2713aSLionel Sambuc
744f4a2713aSLionel Sambuc return false;
745f4a2713aSLionel Sambuc }
746f4a2713aSLionel Sambuc
VisitEnumConstantDecl(EnumConstantDecl * D)747f4a2713aSLionel Sambuc bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748f4a2713aSLionel Sambuc if (Expr *Init = D->getInitExpr())
749f4a2713aSLionel Sambuc return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750f4a2713aSLionel Sambuc return false;
751f4a2713aSLionel Sambuc }
752f4a2713aSLionel Sambuc
VisitDeclaratorDecl(DeclaratorDecl * DD)753f4a2713aSLionel Sambuc bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
754f4a2713aSLionel Sambuc unsigned NumParamList = DD->getNumTemplateParameterLists();
755f4a2713aSLionel Sambuc for (unsigned i = 0; i < NumParamList; i++) {
756f4a2713aSLionel Sambuc TemplateParameterList* Params = DD->getTemplateParameterList(i);
757f4a2713aSLionel Sambuc if (VisitTemplateParameters(Params))
758f4a2713aSLionel Sambuc return true;
759f4a2713aSLionel Sambuc }
760f4a2713aSLionel Sambuc
761f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762f4a2713aSLionel Sambuc if (Visit(TSInfo->getTypeLoc()))
763f4a2713aSLionel Sambuc return true;
764f4a2713aSLionel Sambuc
765f4a2713aSLionel Sambuc // Visit the nested-name-specifier, if present.
766f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
768f4a2713aSLionel Sambuc return true;
769f4a2713aSLionel Sambuc
770f4a2713aSLionel Sambuc return false;
771f4a2713aSLionel Sambuc }
772f4a2713aSLionel Sambuc
773f4a2713aSLionel Sambuc /// \brief Compare two base or member initializers based on their source order.
CompareCXXCtorInitializers(CXXCtorInitializer * const * X,CXXCtorInitializer * const * Y)774f4a2713aSLionel Sambuc static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775f4a2713aSLionel Sambuc CXXCtorInitializer *const *Y) {
776f4a2713aSLionel Sambuc return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777f4a2713aSLionel Sambuc }
778f4a2713aSLionel Sambuc
VisitFunctionDecl(FunctionDecl * ND)779f4a2713aSLionel Sambuc bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
780f4a2713aSLionel Sambuc unsigned NumParamList = ND->getNumTemplateParameterLists();
781f4a2713aSLionel Sambuc for (unsigned i = 0; i < NumParamList; i++) {
782f4a2713aSLionel Sambuc TemplateParameterList* Params = ND->getTemplateParameterList(i);
783f4a2713aSLionel Sambuc if (VisitTemplateParameters(Params))
784f4a2713aSLionel Sambuc return true;
785f4a2713aSLionel Sambuc }
786f4a2713aSLionel Sambuc
787f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788f4a2713aSLionel Sambuc // Visit the function declaration's syntactic components in the order
789f4a2713aSLionel Sambuc // written. This requires a bit of work.
790f4a2713aSLionel Sambuc TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
791f4a2713aSLionel Sambuc FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
792f4a2713aSLionel Sambuc
793f4a2713aSLionel Sambuc // If we have a function declared directly (without the use of a typedef),
794f4a2713aSLionel Sambuc // visit just the return type. Otherwise, just visit the function's type
795f4a2713aSLionel Sambuc // now.
796*0a6a1f1dSLionel Sambuc if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
797f4a2713aSLionel Sambuc (!FTL && Visit(TL)))
798f4a2713aSLionel Sambuc return true;
799f4a2713aSLionel Sambuc
800f4a2713aSLionel Sambuc // Visit the nested-name-specifier, if present.
801f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
803f4a2713aSLionel Sambuc return true;
804f4a2713aSLionel Sambuc
805f4a2713aSLionel Sambuc // Visit the declaration name.
806*0a6a1f1dSLionel Sambuc if (!isa<CXXDestructorDecl>(ND))
807f4a2713aSLionel Sambuc if (VisitDeclarationNameInfo(ND->getNameInfo()))
808f4a2713aSLionel Sambuc return true;
809f4a2713aSLionel Sambuc
810f4a2713aSLionel Sambuc // FIXME: Visit explicitly-specified template arguments!
811f4a2713aSLionel Sambuc
812f4a2713aSLionel Sambuc // Visit the function parameters, if we have a function type.
813f4a2713aSLionel Sambuc if (FTL && VisitFunctionTypeLoc(FTL, true))
814f4a2713aSLionel Sambuc return true;
815f4a2713aSLionel Sambuc
816f4a2713aSLionel Sambuc // FIXME: Attributes?
817f4a2713aSLionel Sambuc }
818f4a2713aSLionel Sambuc
819f4a2713aSLionel Sambuc if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820f4a2713aSLionel Sambuc if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821f4a2713aSLionel Sambuc // Find the initializers that were written in the source.
822f4a2713aSLionel Sambuc SmallVector<CXXCtorInitializer *, 4> WrittenInits;
823*0a6a1f1dSLionel Sambuc for (auto *I : Constructor->inits()) {
824*0a6a1f1dSLionel Sambuc if (!I->isWritten())
825f4a2713aSLionel Sambuc continue;
826f4a2713aSLionel Sambuc
827*0a6a1f1dSLionel Sambuc WrittenInits.push_back(I);
828f4a2713aSLionel Sambuc }
829f4a2713aSLionel Sambuc
830f4a2713aSLionel Sambuc // Sort the initializers in source order
831f4a2713aSLionel Sambuc llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832f4a2713aSLionel Sambuc &CompareCXXCtorInitializers);
833f4a2713aSLionel Sambuc
834f4a2713aSLionel Sambuc // Visit the initializers in source order
835f4a2713aSLionel Sambuc for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836f4a2713aSLionel Sambuc CXXCtorInitializer *Init = WrittenInits[I];
837f4a2713aSLionel Sambuc if (Init->isAnyMemberInitializer()) {
838f4a2713aSLionel Sambuc if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839f4a2713aSLionel Sambuc Init->getMemberLocation(), TU)))
840f4a2713aSLionel Sambuc return true;
841f4a2713aSLionel Sambuc } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842f4a2713aSLionel Sambuc if (Visit(TInfo->getTypeLoc()))
843f4a2713aSLionel Sambuc return true;
844f4a2713aSLionel Sambuc }
845f4a2713aSLionel Sambuc
846f4a2713aSLionel Sambuc // Visit the initializer value.
847f4a2713aSLionel Sambuc if (Expr *Initializer = Init->getInit())
848f4a2713aSLionel Sambuc if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849f4a2713aSLionel Sambuc return true;
850f4a2713aSLionel Sambuc }
851f4a2713aSLionel Sambuc }
852f4a2713aSLionel Sambuc
853f4a2713aSLionel Sambuc if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854f4a2713aSLionel Sambuc return true;
855f4a2713aSLionel Sambuc }
856f4a2713aSLionel Sambuc
857f4a2713aSLionel Sambuc return false;
858f4a2713aSLionel Sambuc }
859f4a2713aSLionel Sambuc
VisitFieldDecl(FieldDecl * D)860f4a2713aSLionel Sambuc bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861f4a2713aSLionel Sambuc if (VisitDeclaratorDecl(D))
862f4a2713aSLionel Sambuc return true;
863f4a2713aSLionel Sambuc
864f4a2713aSLionel Sambuc if (Expr *BitWidth = D->getBitWidth())
865f4a2713aSLionel Sambuc return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866f4a2713aSLionel Sambuc
867f4a2713aSLionel Sambuc return false;
868f4a2713aSLionel Sambuc }
869f4a2713aSLionel Sambuc
VisitVarDecl(VarDecl * D)870f4a2713aSLionel Sambuc bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871f4a2713aSLionel Sambuc if (VisitDeclaratorDecl(D))
872f4a2713aSLionel Sambuc return true;
873f4a2713aSLionel Sambuc
874f4a2713aSLionel Sambuc if (Expr *Init = D->getInit())
875f4a2713aSLionel Sambuc return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876f4a2713aSLionel Sambuc
877f4a2713aSLionel Sambuc return false;
878f4a2713aSLionel Sambuc }
879f4a2713aSLionel Sambuc
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)880f4a2713aSLionel Sambuc bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881f4a2713aSLionel Sambuc if (VisitDeclaratorDecl(D))
882f4a2713aSLionel Sambuc return true;
883f4a2713aSLionel Sambuc
884f4a2713aSLionel Sambuc if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885f4a2713aSLionel Sambuc if (Expr *DefArg = D->getDefaultArgument())
886f4a2713aSLionel Sambuc return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887f4a2713aSLionel Sambuc
888f4a2713aSLionel Sambuc return false;
889f4a2713aSLionel Sambuc }
890f4a2713aSLionel Sambuc
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)891f4a2713aSLionel Sambuc bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892f4a2713aSLionel Sambuc // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893f4a2713aSLionel Sambuc // before visiting these template parameters.
894f4a2713aSLionel Sambuc if (VisitTemplateParameters(D->getTemplateParameters()))
895f4a2713aSLionel Sambuc return true;
896f4a2713aSLionel Sambuc
897f4a2713aSLionel Sambuc return VisitFunctionDecl(D->getTemplatedDecl());
898f4a2713aSLionel Sambuc }
899f4a2713aSLionel Sambuc
VisitClassTemplateDecl(ClassTemplateDecl * D)900f4a2713aSLionel Sambuc bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901f4a2713aSLionel Sambuc // FIXME: Visit the "outer" template parameter lists on the TagDecl
902f4a2713aSLionel Sambuc // before visiting these template parameters.
903f4a2713aSLionel Sambuc if (VisitTemplateParameters(D->getTemplateParameters()))
904f4a2713aSLionel Sambuc return true;
905f4a2713aSLionel Sambuc
906f4a2713aSLionel Sambuc return VisitCXXRecordDecl(D->getTemplatedDecl());
907f4a2713aSLionel Sambuc }
908f4a2713aSLionel Sambuc
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)909f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910f4a2713aSLionel Sambuc if (VisitTemplateParameters(D->getTemplateParameters()))
911f4a2713aSLionel Sambuc return true;
912f4a2713aSLionel Sambuc
913f4a2713aSLionel Sambuc if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914f4a2713aSLionel Sambuc VisitTemplateArgumentLoc(D->getDefaultArgument()))
915f4a2713aSLionel Sambuc return true;
916f4a2713aSLionel Sambuc
917f4a2713aSLionel Sambuc return false;
918f4a2713aSLionel Sambuc }
919f4a2713aSLionel Sambuc
VisitObjCMethodDecl(ObjCMethodDecl * ND)920f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
921*0a6a1f1dSLionel Sambuc if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
922f4a2713aSLionel Sambuc if (Visit(TSInfo->getTypeLoc()))
923f4a2713aSLionel Sambuc return true;
924f4a2713aSLionel Sambuc
925*0a6a1f1dSLionel Sambuc for (const auto *P : ND->params()) {
926*0a6a1f1dSLionel Sambuc if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
927f4a2713aSLionel Sambuc return true;
928f4a2713aSLionel Sambuc }
929f4a2713aSLionel Sambuc
930f4a2713aSLionel Sambuc if (ND->isThisDeclarationADefinition() &&
931f4a2713aSLionel Sambuc Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
932f4a2713aSLionel Sambuc return true;
933f4a2713aSLionel Sambuc
934f4a2713aSLionel Sambuc return false;
935f4a2713aSLionel Sambuc }
936f4a2713aSLionel Sambuc
937f4a2713aSLionel Sambuc template <typename DeclIt>
addRangedDeclsInContainer(DeclIt * DI_current,DeclIt DE_current,SourceManager & SM,SourceLocation EndLoc,SmallVectorImpl<Decl * > & Decls)938f4a2713aSLionel Sambuc static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
939f4a2713aSLionel Sambuc SourceManager &SM, SourceLocation EndLoc,
940f4a2713aSLionel Sambuc SmallVectorImpl<Decl *> &Decls) {
941f4a2713aSLionel Sambuc DeclIt next = *DI_current;
942f4a2713aSLionel Sambuc while (++next != DE_current) {
943f4a2713aSLionel Sambuc Decl *D_next = *next;
944f4a2713aSLionel Sambuc if (!D_next)
945f4a2713aSLionel Sambuc break;
946f4a2713aSLionel Sambuc SourceLocation L = D_next->getLocStart();
947f4a2713aSLionel Sambuc if (!L.isValid())
948f4a2713aSLionel Sambuc break;
949f4a2713aSLionel Sambuc if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
950f4a2713aSLionel Sambuc *DI_current = next;
951f4a2713aSLionel Sambuc Decls.push_back(D_next);
952f4a2713aSLionel Sambuc continue;
953f4a2713aSLionel Sambuc }
954f4a2713aSLionel Sambuc break;
955f4a2713aSLionel Sambuc }
956f4a2713aSLionel Sambuc }
957f4a2713aSLionel Sambuc
VisitObjCContainerDecl(ObjCContainerDecl * D)958f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959f4a2713aSLionel Sambuc // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
960f4a2713aSLionel Sambuc // an @implementation can lexically contain Decls that are not properly
961f4a2713aSLionel Sambuc // nested in the AST. When we identify such cases, we need to retrofit
962f4a2713aSLionel Sambuc // this nesting here.
963f4a2713aSLionel Sambuc if (!DI_current && !FileDI_current)
964f4a2713aSLionel Sambuc return VisitDeclContext(D);
965f4a2713aSLionel Sambuc
966f4a2713aSLionel Sambuc // Scan the Decls that immediately come after the container
967f4a2713aSLionel Sambuc // in the current DeclContext. If any fall within the
968f4a2713aSLionel Sambuc // container's lexical region, stash them into a vector
969f4a2713aSLionel Sambuc // for later processing.
970f4a2713aSLionel Sambuc SmallVector<Decl *, 24> DeclsInContainer;
971f4a2713aSLionel Sambuc SourceLocation EndLoc = D->getSourceRange().getEnd();
972f4a2713aSLionel Sambuc SourceManager &SM = AU->getSourceManager();
973f4a2713aSLionel Sambuc if (EndLoc.isValid()) {
974f4a2713aSLionel Sambuc if (DI_current) {
975f4a2713aSLionel Sambuc addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976f4a2713aSLionel Sambuc DeclsInContainer);
977f4a2713aSLionel Sambuc } else {
978f4a2713aSLionel Sambuc addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979f4a2713aSLionel Sambuc DeclsInContainer);
980f4a2713aSLionel Sambuc }
981f4a2713aSLionel Sambuc }
982f4a2713aSLionel Sambuc
983f4a2713aSLionel Sambuc // The common case.
984f4a2713aSLionel Sambuc if (DeclsInContainer.empty())
985f4a2713aSLionel Sambuc return VisitDeclContext(D);
986f4a2713aSLionel Sambuc
987f4a2713aSLionel Sambuc // Get all the Decls in the DeclContext, and sort them with the
988f4a2713aSLionel Sambuc // additional ones we've collected. Then visit them.
989*0a6a1f1dSLionel Sambuc for (auto *SubDecl : D->decls()) {
990*0a6a1f1dSLionel Sambuc if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
991*0a6a1f1dSLionel Sambuc SubDecl->getLocStart().isInvalid())
992f4a2713aSLionel Sambuc continue;
993*0a6a1f1dSLionel Sambuc DeclsInContainer.push_back(SubDecl);
994f4a2713aSLionel Sambuc }
995f4a2713aSLionel Sambuc
996f4a2713aSLionel Sambuc // Now sort the Decls so that they appear in lexical order.
997f4a2713aSLionel Sambuc std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
998*0a6a1f1dSLionel Sambuc [&SM](Decl *A, Decl *B) {
999*0a6a1f1dSLionel Sambuc SourceLocation L_A = A->getLocStart();
1000*0a6a1f1dSLionel Sambuc SourceLocation L_B = B->getLocStart();
1001*0a6a1f1dSLionel Sambuc assert(L_A.isValid() && L_B.isValid());
1002*0a6a1f1dSLionel Sambuc return SM.isBeforeInTranslationUnit(L_A, L_B);
1003*0a6a1f1dSLionel Sambuc });
1004f4a2713aSLionel Sambuc
1005f4a2713aSLionel Sambuc // Now visit the decls.
1006f4a2713aSLionel Sambuc for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1007f4a2713aSLionel Sambuc E = DeclsInContainer.end(); I != E; ++I) {
1008f4a2713aSLionel Sambuc CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
1009f4a2713aSLionel Sambuc const Optional<bool> &V = shouldVisitCursor(Cursor);
1010f4a2713aSLionel Sambuc if (!V.hasValue())
1011f4a2713aSLionel Sambuc continue;
1012f4a2713aSLionel Sambuc if (!V.getValue())
1013f4a2713aSLionel Sambuc return false;
1014f4a2713aSLionel Sambuc if (Visit(Cursor, true))
1015f4a2713aSLionel Sambuc return true;
1016f4a2713aSLionel Sambuc }
1017f4a2713aSLionel Sambuc return false;
1018f4a2713aSLionel Sambuc }
1019f4a2713aSLionel Sambuc
VisitObjCCategoryDecl(ObjCCategoryDecl * ND)1020f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1021f4a2713aSLionel Sambuc if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1022f4a2713aSLionel Sambuc TU)))
1023f4a2713aSLionel Sambuc return true;
1024f4a2713aSLionel Sambuc
1025f4a2713aSLionel Sambuc ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1026f4a2713aSLionel Sambuc for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1027f4a2713aSLionel Sambuc E = ND->protocol_end(); I != E; ++I, ++PL)
1028f4a2713aSLionel Sambuc if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1029f4a2713aSLionel Sambuc return true;
1030f4a2713aSLionel Sambuc
1031f4a2713aSLionel Sambuc return VisitObjCContainerDecl(ND);
1032f4a2713aSLionel Sambuc }
1033f4a2713aSLionel Sambuc
VisitObjCProtocolDecl(ObjCProtocolDecl * PID)1034f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1035f4a2713aSLionel Sambuc if (!PID->isThisDeclarationADefinition())
1036f4a2713aSLionel Sambuc return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1037f4a2713aSLionel Sambuc
1038f4a2713aSLionel Sambuc ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1039f4a2713aSLionel Sambuc for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1040f4a2713aSLionel Sambuc E = PID->protocol_end(); I != E; ++I, ++PL)
1041f4a2713aSLionel Sambuc if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042f4a2713aSLionel Sambuc return true;
1043f4a2713aSLionel Sambuc
1044f4a2713aSLionel Sambuc return VisitObjCContainerDecl(PID);
1045f4a2713aSLionel Sambuc }
1046f4a2713aSLionel Sambuc
VisitObjCPropertyDecl(ObjCPropertyDecl * PD)1047f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1048f4a2713aSLionel Sambuc if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1049f4a2713aSLionel Sambuc return true;
1050f4a2713aSLionel Sambuc
1051f4a2713aSLionel Sambuc // FIXME: This implements a workaround with @property declarations also being
1052f4a2713aSLionel Sambuc // installed in the DeclContext for the @interface. Eventually this code
1053f4a2713aSLionel Sambuc // should be removed.
1054f4a2713aSLionel Sambuc ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1055f4a2713aSLionel Sambuc if (!CDecl || !CDecl->IsClassExtension())
1056f4a2713aSLionel Sambuc return false;
1057f4a2713aSLionel Sambuc
1058f4a2713aSLionel Sambuc ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1059f4a2713aSLionel Sambuc if (!ID)
1060f4a2713aSLionel Sambuc return false;
1061f4a2713aSLionel Sambuc
1062f4a2713aSLionel Sambuc IdentifierInfo *PropertyId = PD->getIdentifier();
1063f4a2713aSLionel Sambuc ObjCPropertyDecl *prevDecl =
1064f4a2713aSLionel Sambuc ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1065f4a2713aSLionel Sambuc
1066f4a2713aSLionel Sambuc if (!prevDecl)
1067f4a2713aSLionel Sambuc return false;
1068f4a2713aSLionel Sambuc
1069f4a2713aSLionel Sambuc // Visit synthesized methods since they will be skipped when visiting
1070f4a2713aSLionel Sambuc // the @interface.
1071f4a2713aSLionel Sambuc if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1072f4a2713aSLionel Sambuc if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1073f4a2713aSLionel Sambuc if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1074f4a2713aSLionel Sambuc return true;
1075f4a2713aSLionel Sambuc
1076f4a2713aSLionel Sambuc if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1077f4a2713aSLionel Sambuc if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1078f4a2713aSLionel Sambuc if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1079f4a2713aSLionel Sambuc return true;
1080f4a2713aSLionel Sambuc
1081f4a2713aSLionel Sambuc return false;
1082f4a2713aSLionel Sambuc }
1083f4a2713aSLionel Sambuc
VisitObjCInterfaceDecl(ObjCInterfaceDecl * D)1084f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1085f4a2713aSLionel Sambuc if (!D->isThisDeclarationADefinition()) {
1086f4a2713aSLionel Sambuc // Forward declaration is treated like a reference.
1087f4a2713aSLionel Sambuc return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1088f4a2713aSLionel Sambuc }
1089f4a2713aSLionel Sambuc
1090f4a2713aSLionel Sambuc // Issue callbacks for super class.
1091f4a2713aSLionel Sambuc if (D->getSuperClass() &&
1092f4a2713aSLionel Sambuc Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1093f4a2713aSLionel Sambuc D->getSuperClassLoc(),
1094f4a2713aSLionel Sambuc TU)))
1095f4a2713aSLionel Sambuc return true;
1096f4a2713aSLionel Sambuc
1097f4a2713aSLionel Sambuc ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1098f4a2713aSLionel Sambuc for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1099f4a2713aSLionel Sambuc E = D->protocol_end(); I != E; ++I, ++PL)
1100f4a2713aSLionel Sambuc if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101f4a2713aSLionel Sambuc return true;
1102f4a2713aSLionel Sambuc
1103f4a2713aSLionel Sambuc return VisitObjCContainerDecl(D);
1104f4a2713aSLionel Sambuc }
1105f4a2713aSLionel Sambuc
VisitObjCImplDecl(ObjCImplDecl * D)1106f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1107f4a2713aSLionel Sambuc return VisitObjCContainerDecl(D);
1108f4a2713aSLionel Sambuc }
1109f4a2713aSLionel Sambuc
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)1110f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1111f4a2713aSLionel Sambuc // 'ID' could be null when dealing with invalid code.
1112f4a2713aSLionel Sambuc if (ObjCInterfaceDecl *ID = D->getClassInterface())
1113f4a2713aSLionel Sambuc if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1114f4a2713aSLionel Sambuc return true;
1115f4a2713aSLionel Sambuc
1116f4a2713aSLionel Sambuc return VisitObjCImplDecl(D);
1117f4a2713aSLionel Sambuc }
1118f4a2713aSLionel Sambuc
VisitObjCImplementationDecl(ObjCImplementationDecl * D)1119f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1120f4a2713aSLionel Sambuc #if 0
1121f4a2713aSLionel Sambuc // Issue callbacks for super class.
1122f4a2713aSLionel Sambuc // FIXME: No source location information!
1123f4a2713aSLionel Sambuc if (D->getSuperClass() &&
1124f4a2713aSLionel Sambuc Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125f4a2713aSLionel Sambuc D->getSuperClassLoc(),
1126f4a2713aSLionel Sambuc TU)))
1127f4a2713aSLionel Sambuc return true;
1128f4a2713aSLionel Sambuc #endif
1129f4a2713aSLionel Sambuc
1130f4a2713aSLionel Sambuc return VisitObjCImplDecl(D);
1131f4a2713aSLionel Sambuc }
1132f4a2713aSLionel Sambuc
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * PD)1133f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1134f4a2713aSLionel Sambuc if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1135f4a2713aSLionel Sambuc if (PD->isIvarNameSpecified())
1136f4a2713aSLionel Sambuc return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1137f4a2713aSLionel Sambuc
1138f4a2713aSLionel Sambuc return false;
1139f4a2713aSLionel Sambuc }
1140f4a2713aSLionel Sambuc
VisitNamespaceDecl(NamespaceDecl * D)1141f4a2713aSLionel Sambuc bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1142f4a2713aSLionel Sambuc return VisitDeclContext(D);
1143f4a2713aSLionel Sambuc }
1144f4a2713aSLionel Sambuc
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)1145f4a2713aSLionel Sambuc bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1146f4a2713aSLionel Sambuc // Visit nested-name-specifier.
1147f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1148f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149f4a2713aSLionel Sambuc return true;
1150f4a2713aSLionel Sambuc
1151f4a2713aSLionel Sambuc return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1152f4a2713aSLionel Sambuc D->getTargetNameLoc(), TU));
1153f4a2713aSLionel Sambuc }
1154f4a2713aSLionel Sambuc
VisitUsingDecl(UsingDecl * D)1155f4a2713aSLionel Sambuc bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1156f4a2713aSLionel Sambuc // Visit nested-name-specifier.
1157f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1158f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
1159f4a2713aSLionel Sambuc return true;
1160f4a2713aSLionel Sambuc }
1161f4a2713aSLionel Sambuc
1162f4a2713aSLionel Sambuc if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1163f4a2713aSLionel Sambuc return true;
1164f4a2713aSLionel Sambuc
1165f4a2713aSLionel Sambuc return VisitDeclarationNameInfo(D->getNameInfo());
1166f4a2713aSLionel Sambuc }
1167f4a2713aSLionel Sambuc
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)1168f4a2713aSLionel Sambuc bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1169f4a2713aSLionel Sambuc // Visit nested-name-specifier.
1170f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1171f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172f4a2713aSLionel Sambuc return true;
1173f4a2713aSLionel Sambuc
1174f4a2713aSLionel Sambuc return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1175f4a2713aSLionel Sambuc D->getIdentLocation(), TU));
1176f4a2713aSLionel Sambuc }
1177f4a2713aSLionel Sambuc
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)1178f4a2713aSLionel Sambuc bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1179f4a2713aSLionel Sambuc // Visit nested-name-specifier.
1180f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1181f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182f4a2713aSLionel Sambuc return true;
1183f4a2713aSLionel Sambuc }
1184f4a2713aSLionel Sambuc
1185f4a2713aSLionel Sambuc return VisitDeclarationNameInfo(D->getNameInfo());
1186f4a2713aSLionel Sambuc }
1187f4a2713aSLionel Sambuc
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)1188f4a2713aSLionel Sambuc bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1189f4a2713aSLionel Sambuc UnresolvedUsingTypenameDecl *D) {
1190f4a2713aSLionel Sambuc // Visit nested-name-specifier.
1191f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1192f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
1193f4a2713aSLionel Sambuc return true;
1194f4a2713aSLionel Sambuc
1195f4a2713aSLionel Sambuc return false;
1196f4a2713aSLionel Sambuc }
1197f4a2713aSLionel Sambuc
VisitDeclarationNameInfo(DeclarationNameInfo Name)1198f4a2713aSLionel Sambuc bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1199f4a2713aSLionel Sambuc switch (Name.getName().getNameKind()) {
1200f4a2713aSLionel Sambuc case clang::DeclarationName::Identifier:
1201f4a2713aSLionel Sambuc case clang::DeclarationName::CXXLiteralOperatorName:
1202f4a2713aSLionel Sambuc case clang::DeclarationName::CXXOperatorName:
1203f4a2713aSLionel Sambuc case clang::DeclarationName::CXXUsingDirective:
1204f4a2713aSLionel Sambuc return false;
1205f4a2713aSLionel Sambuc
1206f4a2713aSLionel Sambuc case clang::DeclarationName::CXXConstructorName:
1207f4a2713aSLionel Sambuc case clang::DeclarationName::CXXDestructorName:
1208f4a2713aSLionel Sambuc case clang::DeclarationName::CXXConversionFunctionName:
1209f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1210f4a2713aSLionel Sambuc return Visit(TSInfo->getTypeLoc());
1211f4a2713aSLionel Sambuc return false;
1212f4a2713aSLionel Sambuc
1213f4a2713aSLionel Sambuc case clang::DeclarationName::ObjCZeroArgSelector:
1214f4a2713aSLionel Sambuc case clang::DeclarationName::ObjCOneArgSelector:
1215f4a2713aSLionel Sambuc case clang::DeclarationName::ObjCMultiArgSelector:
1216f4a2713aSLionel Sambuc // FIXME: Per-identifier location info?
1217f4a2713aSLionel Sambuc return false;
1218f4a2713aSLionel Sambuc }
1219f4a2713aSLionel Sambuc
1220f4a2713aSLionel Sambuc llvm_unreachable("Invalid DeclarationName::Kind!");
1221f4a2713aSLionel Sambuc }
1222f4a2713aSLionel Sambuc
VisitNestedNameSpecifier(NestedNameSpecifier * NNS,SourceRange Range)1223f4a2713aSLionel Sambuc bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1224f4a2713aSLionel Sambuc SourceRange Range) {
1225f4a2713aSLionel Sambuc // FIXME: This whole routine is a hack to work around the lack of proper
1226f4a2713aSLionel Sambuc // source information in nested-name-specifiers (PR5791). Since we do have
1227f4a2713aSLionel Sambuc // a beginning source location, we can visit the first component of the
1228f4a2713aSLionel Sambuc // nested-name-specifier, if it's a single-token component.
1229f4a2713aSLionel Sambuc if (!NNS)
1230f4a2713aSLionel Sambuc return false;
1231f4a2713aSLionel Sambuc
1232f4a2713aSLionel Sambuc // Get the first component in the nested-name-specifier.
1233f4a2713aSLionel Sambuc while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1234f4a2713aSLionel Sambuc NNS = Prefix;
1235f4a2713aSLionel Sambuc
1236f4a2713aSLionel Sambuc switch (NNS->getKind()) {
1237f4a2713aSLionel Sambuc case NestedNameSpecifier::Namespace:
1238f4a2713aSLionel Sambuc return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1239f4a2713aSLionel Sambuc TU));
1240f4a2713aSLionel Sambuc
1241f4a2713aSLionel Sambuc case NestedNameSpecifier::NamespaceAlias:
1242f4a2713aSLionel Sambuc return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1243f4a2713aSLionel Sambuc Range.getBegin(), TU));
1244f4a2713aSLionel Sambuc
1245f4a2713aSLionel Sambuc case NestedNameSpecifier::TypeSpec: {
1246f4a2713aSLionel Sambuc // If the type has a form where we know that the beginning of the source
1247f4a2713aSLionel Sambuc // range matches up with a reference cursor. Visit the appropriate reference
1248f4a2713aSLionel Sambuc // cursor.
1249f4a2713aSLionel Sambuc const Type *T = NNS->getAsType();
1250f4a2713aSLionel Sambuc if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1251f4a2713aSLionel Sambuc return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1252f4a2713aSLionel Sambuc if (const TagType *Tag = dyn_cast<TagType>(T))
1253f4a2713aSLionel Sambuc return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1254f4a2713aSLionel Sambuc if (const TemplateSpecializationType *TST
1255f4a2713aSLionel Sambuc = dyn_cast<TemplateSpecializationType>(T))
1256f4a2713aSLionel Sambuc return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1257f4a2713aSLionel Sambuc break;
1258f4a2713aSLionel Sambuc }
1259f4a2713aSLionel Sambuc
1260f4a2713aSLionel Sambuc case NestedNameSpecifier::TypeSpecWithTemplate:
1261f4a2713aSLionel Sambuc case NestedNameSpecifier::Global:
1262f4a2713aSLionel Sambuc case NestedNameSpecifier::Identifier:
1263*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::Super:
1264f4a2713aSLionel Sambuc break;
1265f4a2713aSLionel Sambuc }
1266f4a2713aSLionel Sambuc
1267f4a2713aSLionel Sambuc return false;
1268f4a2713aSLionel Sambuc }
1269f4a2713aSLionel Sambuc
1270f4a2713aSLionel Sambuc bool
VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)1271f4a2713aSLionel Sambuc CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1272f4a2713aSLionel Sambuc SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1273f4a2713aSLionel Sambuc for (; Qualifier; Qualifier = Qualifier.getPrefix())
1274f4a2713aSLionel Sambuc Qualifiers.push_back(Qualifier);
1275f4a2713aSLionel Sambuc
1276f4a2713aSLionel Sambuc while (!Qualifiers.empty()) {
1277f4a2713aSLionel Sambuc NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1278f4a2713aSLionel Sambuc NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1279f4a2713aSLionel Sambuc switch (NNS->getKind()) {
1280f4a2713aSLionel Sambuc case NestedNameSpecifier::Namespace:
1281f4a2713aSLionel Sambuc if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1282f4a2713aSLionel Sambuc Q.getLocalBeginLoc(),
1283f4a2713aSLionel Sambuc TU)))
1284f4a2713aSLionel Sambuc return true;
1285f4a2713aSLionel Sambuc
1286f4a2713aSLionel Sambuc break;
1287f4a2713aSLionel Sambuc
1288f4a2713aSLionel Sambuc case NestedNameSpecifier::NamespaceAlias:
1289f4a2713aSLionel Sambuc if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1290f4a2713aSLionel Sambuc Q.getLocalBeginLoc(),
1291f4a2713aSLionel Sambuc TU)))
1292f4a2713aSLionel Sambuc return true;
1293f4a2713aSLionel Sambuc
1294f4a2713aSLionel Sambuc break;
1295f4a2713aSLionel Sambuc
1296f4a2713aSLionel Sambuc case NestedNameSpecifier::TypeSpec:
1297f4a2713aSLionel Sambuc case NestedNameSpecifier::TypeSpecWithTemplate:
1298f4a2713aSLionel Sambuc if (Visit(Q.getTypeLoc()))
1299f4a2713aSLionel Sambuc return true;
1300f4a2713aSLionel Sambuc
1301f4a2713aSLionel Sambuc break;
1302f4a2713aSLionel Sambuc
1303f4a2713aSLionel Sambuc case NestedNameSpecifier::Global:
1304f4a2713aSLionel Sambuc case NestedNameSpecifier::Identifier:
1305*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::Super:
1306f4a2713aSLionel Sambuc break;
1307f4a2713aSLionel Sambuc }
1308f4a2713aSLionel Sambuc }
1309f4a2713aSLionel Sambuc
1310f4a2713aSLionel Sambuc return false;
1311f4a2713aSLionel Sambuc }
1312f4a2713aSLionel Sambuc
VisitTemplateParameters(const TemplateParameterList * Params)1313f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateParameters(
1314f4a2713aSLionel Sambuc const TemplateParameterList *Params) {
1315f4a2713aSLionel Sambuc if (!Params)
1316f4a2713aSLionel Sambuc return false;
1317f4a2713aSLionel Sambuc
1318f4a2713aSLionel Sambuc for (TemplateParameterList::const_iterator P = Params->begin(),
1319f4a2713aSLionel Sambuc PEnd = Params->end();
1320f4a2713aSLionel Sambuc P != PEnd; ++P) {
1321f4a2713aSLionel Sambuc if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1322f4a2713aSLionel Sambuc return true;
1323f4a2713aSLionel Sambuc }
1324f4a2713aSLionel Sambuc
1325f4a2713aSLionel Sambuc return false;
1326f4a2713aSLionel Sambuc }
1327f4a2713aSLionel Sambuc
VisitTemplateName(TemplateName Name,SourceLocation Loc)1328f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1329f4a2713aSLionel Sambuc switch (Name.getKind()) {
1330f4a2713aSLionel Sambuc case TemplateName::Template:
1331f4a2713aSLionel Sambuc return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1332f4a2713aSLionel Sambuc
1333f4a2713aSLionel Sambuc case TemplateName::OverloadedTemplate:
1334f4a2713aSLionel Sambuc // Visit the overloaded template set.
1335f4a2713aSLionel Sambuc if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1336f4a2713aSLionel Sambuc return true;
1337f4a2713aSLionel Sambuc
1338f4a2713aSLionel Sambuc return false;
1339f4a2713aSLionel Sambuc
1340f4a2713aSLionel Sambuc case TemplateName::DependentTemplate:
1341f4a2713aSLionel Sambuc // FIXME: Visit nested-name-specifier.
1342f4a2713aSLionel Sambuc return false;
1343f4a2713aSLionel Sambuc
1344f4a2713aSLionel Sambuc case TemplateName::QualifiedTemplate:
1345f4a2713aSLionel Sambuc // FIXME: Visit nested-name-specifier.
1346f4a2713aSLionel Sambuc return Visit(MakeCursorTemplateRef(
1347f4a2713aSLionel Sambuc Name.getAsQualifiedTemplateName()->getDecl(),
1348f4a2713aSLionel Sambuc Loc, TU));
1349f4a2713aSLionel Sambuc
1350f4a2713aSLionel Sambuc case TemplateName::SubstTemplateTemplateParm:
1351f4a2713aSLionel Sambuc return Visit(MakeCursorTemplateRef(
1352f4a2713aSLionel Sambuc Name.getAsSubstTemplateTemplateParm()->getParameter(),
1353f4a2713aSLionel Sambuc Loc, TU));
1354f4a2713aSLionel Sambuc
1355f4a2713aSLionel Sambuc case TemplateName::SubstTemplateTemplateParmPack:
1356f4a2713aSLionel Sambuc return Visit(MakeCursorTemplateRef(
1357f4a2713aSLionel Sambuc Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1358f4a2713aSLionel Sambuc Loc, TU));
1359f4a2713aSLionel Sambuc }
1360f4a2713aSLionel Sambuc
1361f4a2713aSLionel Sambuc llvm_unreachable("Invalid TemplateName::Kind!");
1362f4a2713aSLionel Sambuc }
1363f4a2713aSLionel Sambuc
VisitTemplateArgumentLoc(const TemplateArgumentLoc & TAL)1364f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1365f4a2713aSLionel Sambuc switch (TAL.getArgument().getKind()) {
1366f4a2713aSLionel Sambuc case TemplateArgument::Null:
1367f4a2713aSLionel Sambuc case TemplateArgument::Integral:
1368f4a2713aSLionel Sambuc case TemplateArgument::Pack:
1369f4a2713aSLionel Sambuc return false;
1370f4a2713aSLionel Sambuc
1371f4a2713aSLionel Sambuc case TemplateArgument::Type:
1372f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1373f4a2713aSLionel Sambuc return Visit(TSInfo->getTypeLoc());
1374f4a2713aSLionel Sambuc return false;
1375f4a2713aSLionel Sambuc
1376f4a2713aSLionel Sambuc case TemplateArgument::Declaration:
1377f4a2713aSLionel Sambuc if (Expr *E = TAL.getSourceDeclExpression())
1378f4a2713aSLionel Sambuc return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379f4a2713aSLionel Sambuc return false;
1380f4a2713aSLionel Sambuc
1381f4a2713aSLionel Sambuc case TemplateArgument::NullPtr:
1382f4a2713aSLionel Sambuc if (Expr *E = TAL.getSourceNullPtrExpression())
1383f4a2713aSLionel Sambuc return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1384f4a2713aSLionel Sambuc return false;
1385f4a2713aSLionel Sambuc
1386f4a2713aSLionel Sambuc case TemplateArgument::Expression:
1387f4a2713aSLionel Sambuc if (Expr *E = TAL.getSourceExpression())
1388f4a2713aSLionel Sambuc return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1389f4a2713aSLionel Sambuc return false;
1390f4a2713aSLionel Sambuc
1391f4a2713aSLionel Sambuc case TemplateArgument::Template:
1392f4a2713aSLionel Sambuc case TemplateArgument::TemplateExpansion:
1393f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1394f4a2713aSLionel Sambuc return true;
1395f4a2713aSLionel Sambuc
1396f4a2713aSLionel Sambuc return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1397f4a2713aSLionel Sambuc TAL.getTemplateNameLoc());
1398f4a2713aSLionel Sambuc }
1399f4a2713aSLionel Sambuc
1400f4a2713aSLionel Sambuc llvm_unreachable("Invalid TemplateArgument::Kind!");
1401f4a2713aSLionel Sambuc }
1402f4a2713aSLionel Sambuc
VisitLinkageSpecDecl(LinkageSpecDecl * D)1403f4a2713aSLionel Sambuc bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1404f4a2713aSLionel Sambuc return VisitDeclContext(D);
1405f4a2713aSLionel Sambuc }
1406f4a2713aSLionel Sambuc
VisitQualifiedTypeLoc(QualifiedTypeLoc TL)1407f4a2713aSLionel Sambuc bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1408f4a2713aSLionel Sambuc return Visit(TL.getUnqualifiedLoc());
1409f4a2713aSLionel Sambuc }
1410f4a2713aSLionel Sambuc
VisitBuiltinTypeLoc(BuiltinTypeLoc TL)1411f4a2713aSLionel Sambuc bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1412f4a2713aSLionel Sambuc ASTContext &Context = AU->getASTContext();
1413f4a2713aSLionel Sambuc
1414f4a2713aSLionel Sambuc // Some builtin types (such as Objective-C's "id", "sel", and
1415f4a2713aSLionel Sambuc // "Class") have associated declarations. Create cursors for those.
1416f4a2713aSLionel Sambuc QualType VisitType;
1417f4a2713aSLionel Sambuc switch (TL.getTypePtr()->getKind()) {
1418f4a2713aSLionel Sambuc
1419f4a2713aSLionel Sambuc case BuiltinType::Void:
1420f4a2713aSLionel Sambuc case BuiltinType::NullPtr:
1421f4a2713aSLionel Sambuc case BuiltinType::Dependent:
1422f4a2713aSLionel Sambuc case BuiltinType::OCLImage1d:
1423f4a2713aSLionel Sambuc case BuiltinType::OCLImage1dArray:
1424f4a2713aSLionel Sambuc case BuiltinType::OCLImage1dBuffer:
1425f4a2713aSLionel Sambuc case BuiltinType::OCLImage2d:
1426f4a2713aSLionel Sambuc case BuiltinType::OCLImage2dArray:
1427f4a2713aSLionel Sambuc case BuiltinType::OCLImage3d:
1428f4a2713aSLionel Sambuc case BuiltinType::OCLSampler:
1429f4a2713aSLionel Sambuc case BuiltinType::OCLEvent:
1430f4a2713aSLionel Sambuc #define BUILTIN_TYPE(Id, SingletonId)
1431f4a2713aSLionel Sambuc #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432f4a2713aSLionel Sambuc #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1433f4a2713aSLionel Sambuc #define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1434f4a2713aSLionel Sambuc #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1435f4a2713aSLionel Sambuc #include "clang/AST/BuiltinTypes.def"
1436f4a2713aSLionel Sambuc break;
1437f4a2713aSLionel Sambuc
1438f4a2713aSLionel Sambuc case BuiltinType::ObjCId:
1439f4a2713aSLionel Sambuc VisitType = Context.getObjCIdType();
1440f4a2713aSLionel Sambuc break;
1441f4a2713aSLionel Sambuc
1442f4a2713aSLionel Sambuc case BuiltinType::ObjCClass:
1443f4a2713aSLionel Sambuc VisitType = Context.getObjCClassType();
1444f4a2713aSLionel Sambuc break;
1445f4a2713aSLionel Sambuc
1446f4a2713aSLionel Sambuc case BuiltinType::ObjCSel:
1447f4a2713aSLionel Sambuc VisitType = Context.getObjCSelType();
1448f4a2713aSLionel Sambuc break;
1449f4a2713aSLionel Sambuc }
1450f4a2713aSLionel Sambuc
1451f4a2713aSLionel Sambuc if (!VisitType.isNull()) {
1452f4a2713aSLionel Sambuc if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1453f4a2713aSLionel Sambuc return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1454f4a2713aSLionel Sambuc TU));
1455f4a2713aSLionel Sambuc }
1456f4a2713aSLionel Sambuc
1457f4a2713aSLionel Sambuc return false;
1458f4a2713aSLionel Sambuc }
1459f4a2713aSLionel Sambuc
VisitTypedefTypeLoc(TypedefTypeLoc TL)1460f4a2713aSLionel Sambuc bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1461f4a2713aSLionel Sambuc return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1462f4a2713aSLionel Sambuc }
1463f4a2713aSLionel Sambuc
VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL)1464f4a2713aSLionel Sambuc bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1465f4a2713aSLionel Sambuc return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1466f4a2713aSLionel Sambuc }
1467f4a2713aSLionel Sambuc
VisitTagTypeLoc(TagTypeLoc TL)1468f4a2713aSLionel Sambuc bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1469f4a2713aSLionel Sambuc if (TL.isDefinition())
1470f4a2713aSLionel Sambuc return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1471f4a2713aSLionel Sambuc
1472f4a2713aSLionel Sambuc return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1473f4a2713aSLionel Sambuc }
1474f4a2713aSLionel Sambuc
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)1475f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1476f4a2713aSLionel Sambuc return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1477f4a2713aSLionel Sambuc }
1478f4a2713aSLionel Sambuc
VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL)1479f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1480f4a2713aSLionel Sambuc if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1481f4a2713aSLionel Sambuc return true;
1482f4a2713aSLionel Sambuc
1483f4a2713aSLionel Sambuc return false;
1484f4a2713aSLionel Sambuc }
1485f4a2713aSLionel Sambuc
VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL)1486f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1487f4a2713aSLionel Sambuc if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1488f4a2713aSLionel Sambuc return true;
1489f4a2713aSLionel Sambuc
1490f4a2713aSLionel Sambuc for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1491f4a2713aSLionel Sambuc if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1492f4a2713aSLionel Sambuc TU)))
1493f4a2713aSLionel Sambuc return true;
1494f4a2713aSLionel Sambuc }
1495f4a2713aSLionel Sambuc
1496f4a2713aSLionel Sambuc return false;
1497f4a2713aSLionel Sambuc }
1498f4a2713aSLionel Sambuc
VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL)1499f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1500f4a2713aSLionel Sambuc return Visit(TL.getPointeeLoc());
1501f4a2713aSLionel Sambuc }
1502f4a2713aSLionel Sambuc
VisitParenTypeLoc(ParenTypeLoc TL)1503f4a2713aSLionel Sambuc bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1504f4a2713aSLionel Sambuc return Visit(TL.getInnerLoc());
1505f4a2713aSLionel Sambuc }
1506f4a2713aSLionel Sambuc
VisitPointerTypeLoc(PointerTypeLoc TL)1507f4a2713aSLionel Sambuc bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1508f4a2713aSLionel Sambuc return Visit(TL.getPointeeLoc());
1509f4a2713aSLionel Sambuc }
1510f4a2713aSLionel Sambuc
VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL)1511f4a2713aSLionel Sambuc bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1512f4a2713aSLionel Sambuc return Visit(TL.getPointeeLoc());
1513f4a2713aSLionel Sambuc }
1514f4a2713aSLionel Sambuc
VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL)1515f4a2713aSLionel Sambuc bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1516f4a2713aSLionel Sambuc return Visit(TL.getPointeeLoc());
1517f4a2713aSLionel Sambuc }
1518f4a2713aSLionel Sambuc
VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL)1519f4a2713aSLionel Sambuc bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1520f4a2713aSLionel Sambuc return Visit(TL.getPointeeLoc());
1521f4a2713aSLionel Sambuc }
1522f4a2713aSLionel Sambuc
VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL)1523f4a2713aSLionel Sambuc bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1524f4a2713aSLionel Sambuc return Visit(TL.getPointeeLoc());
1525f4a2713aSLionel Sambuc }
1526f4a2713aSLionel Sambuc
VisitAttributedTypeLoc(AttributedTypeLoc TL)1527f4a2713aSLionel Sambuc bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1528f4a2713aSLionel Sambuc return Visit(TL.getModifiedLoc());
1529f4a2713aSLionel Sambuc }
1530f4a2713aSLionel Sambuc
VisitFunctionTypeLoc(FunctionTypeLoc TL,bool SkipResultType)1531f4a2713aSLionel Sambuc bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1532f4a2713aSLionel Sambuc bool SkipResultType) {
1533*0a6a1f1dSLionel Sambuc if (!SkipResultType && Visit(TL.getReturnLoc()))
1534f4a2713aSLionel Sambuc return true;
1535f4a2713aSLionel Sambuc
1536*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1537*0a6a1f1dSLionel Sambuc if (Decl *D = TL.getParam(I))
1538f4a2713aSLionel Sambuc if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1539f4a2713aSLionel Sambuc return true;
1540f4a2713aSLionel Sambuc
1541f4a2713aSLionel Sambuc return false;
1542f4a2713aSLionel Sambuc }
1543f4a2713aSLionel Sambuc
VisitArrayTypeLoc(ArrayTypeLoc TL)1544f4a2713aSLionel Sambuc bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1545f4a2713aSLionel Sambuc if (Visit(TL.getElementLoc()))
1546f4a2713aSLionel Sambuc return true;
1547f4a2713aSLionel Sambuc
1548f4a2713aSLionel Sambuc if (Expr *Size = TL.getSizeExpr())
1549f4a2713aSLionel Sambuc return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1550f4a2713aSLionel Sambuc
1551f4a2713aSLionel Sambuc return false;
1552f4a2713aSLionel Sambuc }
1553f4a2713aSLionel Sambuc
VisitDecayedTypeLoc(DecayedTypeLoc TL)1554f4a2713aSLionel Sambuc bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1555f4a2713aSLionel Sambuc return Visit(TL.getOriginalLoc());
1556f4a2713aSLionel Sambuc }
1557f4a2713aSLionel Sambuc
VisitAdjustedTypeLoc(AdjustedTypeLoc TL)1558*0a6a1f1dSLionel Sambuc bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1559*0a6a1f1dSLionel Sambuc return Visit(TL.getOriginalLoc());
1560*0a6a1f1dSLionel Sambuc }
1561*0a6a1f1dSLionel Sambuc
VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)1562f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1563f4a2713aSLionel Sambuc TemplateSpecializationTypeLoc TL) {
1564f4a2713aSLionel Sambuc // Visit the template name.
1565f4a2713aSLionel Sambuc if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1566f4a2713aSLionel Sambuc TL.getTemplateNameLoc()))
1567f4a2713aSLionel Sambuc return true;
1568f4a2713aSLionel Sambuc
1569f4a2713aSLionel Sambuc // Visit the template arguments.
1570f4a2713aSLionel Sambuc for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1571f4a2713aSLionel Sambuc if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1572f4a2713aSLionel Sambuc return true;
1573f4a2713aSLionel Sambuc
1574f4a2713aSLionel Sambuc return false;
1575f4a2713aSLionel Sambuc }
1576f4a2713aSLionel Sambuc
VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL)1577f4a2713aSLionel Sambuc bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1578f4a2713aSLionel Sambuc return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1579f4a2713aSLionel Sambuc }
1580f4a2713aSLionel Sambuc
VisitTypeOfTypeLoc(TypeOfTypeLoc TL)1581f4a2713aSLionel Sambuc bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1582f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1583f4a2713aSLionel Sambuc return Visit(TSInfo->getTypeLoc());
1584f4a2713aSLionel Sambuc
1585f4a2713aSLionel Sambuc return false;
1586f4a2713aSLionel Sambuc }
1587f4a2713aSLionel Sambuc
VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL)1588f4a2713aSLionel Sambuc bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1589f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1590f4a2713aSLionel Sambuc return Visit(TSInfo->getTypeLoc());
1591f4a2713aSLionel Sambuc
1592f4a2713aSLionel Sambuc return false;
1593f4a2713aSLionel Sambuc }
1594f4a2713aSLionel Sambuc
VisitDependentNameTypeLoc(DependentNameTypeLoc TL)1595f4a2713aSLionel Sambuc bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1596f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1597f4a2713aSLionel Sambuc return true;
1598f4a2713aSLionel Sambuc
1599f4a2713aSLionel Sambuc return false;
1600f4a2713aSLionel Sambuc }
1601f4a2713aSLionel Sambuc
VisitDependentTemplateSpecializationTypeLoc(DependentTemplateSpecializationTypeLoc TL)1602f4a2713aSLionel Sambuc bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1603f4a2713aSLionel Sambuc DependentTemplateSpecializationTypeLoc TL) {
1604f4a2713aSLionel Sambuc // Visit the nested-name-specifier, if there is one.
1605f4a2713aSLionel Sambuc if (TL.getQualifierLoc() &&
1606f4a2713aSLionel Sambuc VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1607f4a2713aSLionel Sambuc return true;
1608f4a2713aSLionel Sambuc
1609f4a2713aSLionel Sambuc // Visit the template arguments.
1610f4a2713aSLionel Sambuc for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1611f4a2713aSLionel Sambuc if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1612f4a2713aSLionel Sambuc return true;
1613f4a2713aSLionel Sambuc
1614f4a2713aSLionel Sambuc return false;
1615f4a2713aSLionel Sambuc }
1616f4a2713aSLionel Sambuc
VisitElaboratedTypeLoc(ElaboratedTypeLoc TL)1617f4a2713aSLionel Sambuc bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1618f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1619f4a2713aSLionel Sambuc return true;
1620f4a2713aSLionel Sambuc
1621f4a2713aSLionel Sambuc return Visit(TL.getNamedTypeLoc());
1622f4a2713aSLionel Sambuc }
1623f4a2713aSLionel Sambuc
VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL)1624f4a2713aSLionel Sambuc bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1625f4a2713aSLionel Sambuc return Visit(TL.getPatternLoc());
1626f4a2713aSLionel Sambuc }
1627f4a2713aSLionel Sambuc
VisitDecltypeTypeLoc(DecltypeTypeLoc TL)1628f4a2713aSLionel Sambuc bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1629f4a2713aSLionel Sambuc if (Expr *E = TL.getUnderlyingExpr())
1630f4a2713aSLionel Sambuc return Visit(MakeCXCursor(E, StmtParent, TU));
1631f4a2713aSLionel Sambuc
1632f4a2713aSLionel Sambuc return false;
1633f4a2713aSLionel Sambuc }
1634f4a2713aSLionel Sambuc
VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL)1635f4a2713aSLionel Sambuc bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1636f4a2713aSLionel Sambuc return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1637f4a2713aSLionel Sambuc }
1638f4a2713aSLionel Sambuc
VisitAtomicTypeLoc(AtomicTypeLoc TL)1639f4a2713aSLionel Sambuc bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1640f4a2713aSLionel Sambuc return Visit(TL.getValueLoc());
1641f4a2713aSLionel Sambuc }
1642f4a2713aSLionel Sambuc
1643f4a2713aSLionel Sambuc #define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1644f4a2713aSLionel Sambuc bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1645f4a2713aSLionel Sambuc return Visit##PARENT##Loc(TL); \
1646f4a2713aSLionel Sambuc }
1647f4a2713aSLionel Sambuc
DEFAULT_TYPELOC_IMPL(Complex,Type)1648f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(Complex, Type)
1649f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1650f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1651f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1652f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1653f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1654f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(Vector, Type)
1655f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1656f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1657f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1658f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(Record, TagType)
1659f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(Enum, TagType)
1660f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1661f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1662f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(Auto, Type)
1663f4a2713aSLionel Sambuc
1664f4a2713aSLionel Sambuc bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1665f4a2713aSLionel Sambuc // Visit the nested-name-specifier, if present.
1666f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1667f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
1668f4a2713aSLionel Sambuc return true;
1669f4a2713aSLionel Sambuc
1670f4a2713aSLionel Sambuc if (D->isCompleteDefinition()) {
1671*0a6a1f1dSLionel Sambuc for (const auto &I : D->bases()) {
1672*0a6a1f1dSLionel Sambuc if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
1673f4a2713aSLionel Sambuc return true;
1674f4a2713aSLionel Sambuc }
1675f4a2713aSLionel Sambuc }
1676f4a2713aSLionel Sambuc
1677f4a2713aSLionel Sambuc return VisitTagDecl(D);
1678f4a2713aSLionel Sambuc }
1679f4a2713aSLionel Sambuc
VisitAttributes(Decl * D)1680f4a2713aSLionel Sambuc bool CursorVisitor::VisitAttributes(Decl *D) {
1681*0a6a1f1dSLionel Sambuc for (const auto *I : D->attrs())
1682*0a6a1f1dSLionel Sambuc if (Visit(MakeCXCursor(I, D, TU)))
1683f4a2713aSLionel Sambuc return true;
1684f4a2713aSLionel Sambuc
1685f4a2713aSLionel Sambuc return false;
1686f4a2713aSLionel Sambuc }
1687f4a2713aSLionel Sambuc
1688f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1689f4a2713aSLionel Sambuc // Data-recursive visitor methods.
1690f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1691f4a2713aSLionel Sambuc
1692f4a2713aSLionel Sambuc namespace {
1693f4a2713aSLionel Sambuc #define DEF_JOB(NAME, DATA, KIND)\
1694f4a2713aSLionel Sambuc class NAME : public VisitorJob {\
1695f4a2713aSLionel Sambuc public:\
1696f4a2713aSLionel Sambuc NAME(const DATA *d, CXCursor parent) : \
1697f4a2713aSLionel Sambuc VisitorJob(parent, VisitorJob::KIND, d) {} \
1698f4a2713aSLionel Sambuc static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
1699f4a2713aSLionel Sambuc const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
1700f4a2713aSLionel Sambuc };
1701f4a2713aSLionel Sambuc
1702f4a2713aSLionel Sambuc DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1703f4a2713aSLionel Sambuc DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1704f4a2713aSLionel Sambuc DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1705f4a2713aSLionel Sambuc DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1706f4a2713aSLionel Sambuc DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1707f4a2713aSLionel Sambuc ExplicitTemplateArgsVisitKind)
1708f4a2713aSLionel Sambuc DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1709f4a2713aSLionel Sambuc DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1710f4a2713aSLionel Sambuc DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1711f4a2713aSLionel Sambuc #undef DEF_JOB
1712f4a2713aSLionel Sambuc
1713f4a2713aSLionel Sambuc class DeclVisit : public VisitorJob {
1714f4a2713aSLionel Sambuc public:
DeclVisit(const Decl * D,CXCursor parent,bool isFirst)1715f4a2713aSLionel Sambuc DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
1716f4a2713aSLionel Sambuc VisitorJob(parent, VisitorJob::DeclVisitKind,
1717*0a6a1f1dSLionel Sambuc D, isFirst ? (void*) 1 : (void*) nullptr) {}
classof(const VisitorJob * VJ)1718f4a2713aSLionel Sambuc static bool classof(const VisitorJob *VJ) {
1719f4a2713aSLionel Sambuc return VJ->getKind() == DeclVisitKind;
1720f4a2713aSLionel Sambuc }
get() const1721f4a2713aSLionel Sambuc const Decl *get() const { return static_cast<const Decl *>(data[0]); }
isFirst() const1722f4a2713aSLionel Sambuc bool isFirst() const { return data[1] ? true : false; }
1723f4a2713aSLionel Sambuc };
1724f4a2713aSLionel Sambuc class TypeLocVisit : public VisitorJob {
1725f4a2713aSLionel Sambuc public:
TypeLocVisit(TypeLoc tl,CXCursor parent)1726f4a2713aSLionel Sambuc TypeLocVisit(TypeLoc tl, CXCursor parent) :
1727f4a2713aSLionel Sambuc VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1728f4a2713aSLionel Sambuc tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1729f4a2713aSLionel Sambuc
classof(const VisitorJob * VJ)1730f4a2713aSLionel Sambuc static bool classof(const VisitorJob *VJ) {
1731f4a2713aSLionel Sambuc return VJ->getKind() == TypeLocVisitKind;
1732f4a2713aSLionel Sambuc }
1733f4a2713aSLionel Sambuc
get() const1734f4a2713aSLionel Sambuc TypeLoc get() const {
1735f4a2713aSLionel Sambuc QualType T = QualType::getFromOpaquePtr(data[0]);
1736f4a2713aSLionel Sambuc return TypeLoc(T, const_cast<void *>(data[1]));
1737f4a2713aSLionel Sambuc }
1738f4a2713aSLionel Sambuc };
1739f4a2713aSLionel Sambuc
1740f4a2713aSLionel Sambuc class LabelRefVisit : public VisitorJob {
1741f4a2713aSLionel Sambuc public:
LabelRefVisit(LabelDecl * LD,SourceLocation labelLoc,CXCursor parent)1742f4a2713aSLionel Sambuc LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1743f4a2713aSLionel Sambuc : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1744f4a2713aSLionel Sambuc labelLoc.getPtrEncoding()) {}
1745f4a2713aSLionel Sambuc
classof(const VisitorJob * VJ)1746f4a2713aSLionel Sambuc static bool classof(const VisitorJob *VJ) {
1747f4a2713aSLionel Sambuc return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1748f4a2713aSLionel Sambuc }
get() const1749f4a2713aSLionel Sambuc const LabelDecl *get() const {
1750f4a2713aSLionel Sambuc return static_cast<const LabelDecl *>(data[0]);
1751f4a2713aSLionel Sambuc }
getLoc() const1752f4a2713aSLionel Sambuc SourceLocation getLoc() const {
1753f4a2713aSLionel Sambuc return SourceLocation::getFromPtrEncoding(data[1]); }
1754f4a2713aSLionel Sambuc };
1755f4a2713aSLionel Sambuc
1756f4a2713aSLionel Sambuc class NestedNameSpecifierLocVisit : public VisitorJob {
1757f4a2713aSLionel Sambuc public:
NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier,CXCursor parent)1758f4a2713aSLionel Sambuc NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1759f4a2713aSLionel Sambuc : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1760f4a2713aSLionel Sambuc Qualifier.getNestedNameSpecifier(),
1761f4a2713aSLionel Sambuc Qualifier.getOpaqueData()) { }
1762f4a2713aSLionel Sambuc
classof(const VisitorJob * VJ)1763f4a2713aSLionel Sambuc static bool classof(const VisitorJob *VJ) {
1764f4a2713aSLionel Sambuc return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1765f4a2713aSLionel Sambuc }
1766f4a2713aSLionel Sambuc
get() const1767f4a2713aSLionel Sambuc NestedNameSpecifierLoc get() const {
1768f4a2713aSLionel Sambuc return NestedNameSpecifierLoc(
1769f4a2713aSLionel Sambuc const_cast<NestedNameSpecifier *>(
1770f4a2713aSLionel Sambuc static_cast<const NestedNameSpecifier *>(data[0])),
1771f4a2713aSLionel Sambuc const_cast<void *>(data[1]));
1772f4a2713aSLionel Sambuc }
1773f4a2713aSLionel Sambuc };
1774f4a2713aSLionel Sambuc
1775f4a2713aSLionel Sambuc class DeclarationNameInfoVisit : public VisitorJob {
1776f4a2713aSLionel Sambuc public:
DeclarationNameInfoVisit(const Stmt * S,CXCursor parent)1777f4a2713aSLionel Sambuc DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
1778f4a2713aSLionel Sambuc : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
classof(const VisitorJob * VJ)1779f4a2713aSLionel Sambuc static bool classof(const VisitorJob *VJ) {
1780f4a2713aSLionel Sambuc return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1781f4a2713aSLionel Sambuc }
get() const1782f4a2713aSLionel Sambuc DeclarationNameInfo get() const {
1783f4a2713aSLionel Sambuc const Stmt *S = static_cast<const Stmt *>(data[0]);
1784f4a2713aSLionel Sambuc switch (S->getStmtClass()) {
1785f4a2713aSLionel Sambuc default:
1786f4a2713aSLionel Sambuc llvm_unreachable("Unhandled Stmt");
1787f4a2713aSLionel Sambuc case clang::Stmt::MSDependentExistsStmtClass:
1788f4a2713aSLionel Sambuc return cast<MSDependentExistsStmt>(S)->getNameInfo();
1789f4a2713aSLionel Sambuc case Stmt::CXXDependentScopeMemberExprClass:
1790f4a2713aSLionel Sambuc return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1791f4a2713aSLionel Sambuc case Stmt::DependentScopeDeclRefExprClass:
1792f4a2713aSLionel Sambuc return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1793*0a6a1f1dSLionel Sambuc case Stmt::OMPCriticalDirectiveClass:
1794*0a6a1f1dSLionel Sambuc return cast<OMPCriticalDirective>(S)->getDirectiveName();
1795f4a2713aSLionel Sambuc }
1796f4a2713aSLionel Sambuc }
1797f4a2713aSLionel Sambuc };
1798f4a2713aSLionel Sambuc class MemberRefVisit : public VisitorJob {
1799f4a2713aSLionel Sambuc public:
MemberRefVisit(const FieldDecl * D,SourceLocation L,CXCursor parent)1800f4a2713aSLionel Sambuc MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
1801f4a2713aSLionel Sambuc : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1802f4a2713aSLionel Sambuc L.getPtrEncoding()) {}
classof(const VisitorJob * VJ)1803f4a2713aSLionel Sambuc static bool classof(const VisitorJob *VJ) {
1804f4a2713aSLionel Sambuc return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1805f4a2713aSLionel Sambuc }
get() const1806f4a2713aSLionel Sambuc const FieldDecl *get() const {
1807f4a2713aSLionel Sambuc return static_cast<const FieldDecl *>(data[0]);
1808f4a2713aSLionel Sambuc }
getLoc() const1809f4a2713aSLionel Sambuc SourceLocation getLoc() const {
1810f4a2713aSLionel Sambuc return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1811f4a2713aSLionel Sambuc }
1812f4a2713aSLionel Sambuc };
1813f4a2713aSLionel Sambuc class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
1814f4a2713aSLionel Sambuc friend class OMPClauseEnqueue;
1815f4a2713aSLionel Sambuc VisitorWorkList &WL;
1816f4a2713aSLionel Sambuc CXCursor Parent;
1817f4a2713aSLionel Sambuc public:
EnqueueVisitor(VisitorWorkList & wl,CXCursor parent)1818f4a2713aSLionel Sambuc EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1819f4a2713aSLionel Sambuc : WL(wl), Parent(parent) {}
1820f4a2713aSLionel Sambuc
1821f4a2713aSLionel Sambuc void VisitAddrLabelExpr(const AddrLabelExpr *E);
1822f4a2713aSLionel Sambuc void VisitBlockExpr(const BlockExpr *B);
1823f4a2713aSLionel Sambuc void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1824f4a2713aSLionel Sambuc void VisitCompoundStmt(const CompoundStmt *S);
VisitCXXDefaultArgExpr(const CXXDefaultArgExpr * E)1825f4a2713aSLionel Sambuc void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1826f4a2713aSLionel Sambuc void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1827f4a2713aSLionel Sambuc void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1828f4a2713aSLionel Sambuc void VisitCXXNewExpr(const CXXNewExpr *E);
1829f4a2713aSLionel Sambuc void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1830f4a2713aSLionel Sambuc void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1831f4a2713aSLionel Sambuc void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1832f4a2713aSLionel Sambuc void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1833f4a2713aSLionel Sambuc void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1834f4a2713aSLionel Sambuc void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1835f4a2713aSLionel Sambuc void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1836f4a2713aSLionel Sambuc void VisitCXXCatchStmt(const CXXCatchStmt *S);
1837*0a6a1f1dSLionel Sambuc void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
1838f4a2713aSLionel Sambuc void VisitDeclRefExpr(const DeclRefExpr *D);
1839f4a2713aSLionel Sambuc void VisitDeclStmt(const DeclStmt *S);
1840f4a2713aSLionel Sambuc void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1841f4a2713aSLionel Sambuc void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1842f4a2713aSLionel Sambuc void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1843f4a2713aSLionel Sambuc void VisitForStmt(const ForStmt *FS);
1844f4a2713aSLionel Sambuc void VisitGotoStmt(const GotoStmt *GS);
1845f4a2713aSLionel Sambuc void VisitIfStmt(const IfStmt *If);
1846f4a2713aSLionel Sambuc void VisitInitListExpr(const InitListExpr *IE);
1847f4a2713aSLionel Sambuc void VisitMemberExpr(const MemberExpr *M);
1848f4a2713aSLionel Sambuc void VisitOffsetOfExpr(const OffsetOfExpr *E);
1849f4a2713aSLionel Sambuc void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1850f4a2713aSLionel Sambuc void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1851f4a2713aSLionel Sambuc void VisitOverloadExpr(const OverloadExpr *E);
1852f4a2713aSLionel Sambuc void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1853f4a2713aSLionel Sambuc void VisitStmt(const Stmt *S);
1854f4a2713aSLionel Sambuc void VisitSwitchStmt(const SwitchStmt *S);
1855f4a2713aSLionel Sambuc void VisitWhileStmt(const WhileStmt *W);
1856f4a2713aSLionel Sambuc void VisitTypeTraitExpr(const TypeTraitExpr *E);
1857f4a2713aSLionel Sambuc void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1858f4a2713aSLionel Sambuc void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1859f4a2713aSLionel Sambuc void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1860f4a2713aSLionel Sambuc void VisitVAArgExpr(const VAArgExpr *E);
1861f4a2713aSLionel Sambuc void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1862f4a2713aSLionel Sambuc void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1863f4a2713aSLionel Sambuc void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1864f4a2713aSLionel Sambuc void VisitLambdaExpr(const LambdaExpr *E);
1865f4a2713aSLionel Sambuc void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1866*0a6a1f1dSLionel Sambuc void VisitOMPLoopDirective(const OMPLoopDirective *D);
1867f4a2713aSLionel Sambuc void VisitOMPParallelDirective(const OMPParallelDirective *D);
1868*0a6a1f1dSLionel Sambuc void VisitOMPSimdDirective(const OMPSimdDirective *D);
1869*0a6a1f1dSLionel Sambuc void VisitOMPForDirective(const OMPForDirective *D);
1870*0a6a1f1dSLionel Sambuc void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
1871*0a6a1f1dSLionel Sambuc void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
1872*0a6a1f1dSLionel Sambuc void VisitOMPSectionDirective(const OMPSectionDirective *D);
1873*0a6a1f1dSLionel Sambuc void VisitOMPSingleDirective(const OMPSingleDirective *D);
1874*0a6a1f1dSLionel Sambuc void VisitOMPMasterDirective(const OMPMasterDirective *D);
1875*0a6a1f1dSLionel Sambuc void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
1876*0a6a1f1dSLionel Sambuc void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
1877*0a6a1f1dSLionel Sambuc void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
1878*0a6a1f1dSLionel Sambuc void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
1879*0a6a1f1dSLionel Sambuc void VisitOMPTaskDirective(const OMPTaskDirective *D);
1880*0a6a1f1dSLionel Sambuc void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
1881*0a6a1f1dSLionel Sambuc void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
1882*0a6a1f1dSLionel Sambuc void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
1883*0a6a1f1dSLionel Sambuc void VisitOMPFlushDirective(const OMPFlushDirective *D);
1884*0a6a1f1dSLionel Sambuc void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
1885*0a6a1f1dSLionel Sambuc void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
1886*0a6a1f1dSLionel Sambuc void VisitOMPTargetDirective(const OMPTargetDirective *D);
1887*0a6a1f1dSLionel Sambuc void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
1888f4a2713aSLionel Sambuc
1889f4a2713aSLionel Sambuc private:
1890f4a2713aSLionel Sambuc void AddDeclarationNameInfo(const Stmt *S);
1891f4a2713aSLionel Sambuc void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1892f4a2713aSLionel Sambuc void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
1893f4a2713aSLionel Sambuc void AddMemberRef(const FieldDecl *D, SourceLocation L);
1894f4a2713aSLionel Sambuc void AddStmt(const Stmt *S);
1895f4a2713aSLionel Sambuc void AddDecl(const Decl *D, bool isFirst = true);
1896f4a2713aSLionel Sambuc void AddTypeLoc(TypeSourceInfo *TI);
1897f4a2713aSLionel Sambuc void EnqueueChildren(const Stmt *S);
1898f4a2713aSLionel Sambuc void EnqueueChildren(const OMPClause *S);
1899f4a2713aSLionel Sambuc };
1900f4a2713aSLionel Sambuc } // end anonyous namespace
1901f4a2713aSLionel Sambuc
AddDeclarationNameInfo(const Stmt * S)1902f4a2713aSLionel Sambuc void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
1903f4a2713aSLionel Sambuc // 'S' should always be non-null, since it comes from the
1904f4a2713aSLionel Sambuc // statement we are visiting.
1905f4a2713aSLionel Sambuc WL.push_back(DeclarationNameInfoVisit(S, Parent));
1906f4a2713aSLionel Sambuc }
1907f4a2713aSLionel Sambuc
1908f4a2713aSLionel Sambuc void
AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)1909f4a2713aSLionel Sambuc EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1910f4a2713aSLionel Sambuc if (Qualifier)
1911f4a2713aSLionel Sambuc WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1912f4a2713aSLionel Sambuc }
1913f4a2713aSLionel Sambuc
AddStmt(const Stmt * S)1914f4a2713aSLionel Sambuc void EnqueueVisitor::AddStmt(const Stmt *S) {
1915f4a2713aSLionel Sambuc if (S)
1916f4a2713aSLionel Sambuc WL.push_back(StmtVisit(S, Parent));
1917f4a2713aSLionel Sambuc }
AddDecl(const Decl * D,bool isFirst)1918f4a2713aSLionel Sambuc void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
1919f4a2713aSLionel Sambuc if (D)
1920f4a2713aSLionel Sambuc WL.push_back(DeclVisit(D, Parent, isFirst));
1921f4a2713aSLionel Sambuc }
1922f4a2713aSLionel Sambuc void EnqueueVisitor::
AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo * A)1923f4a2713aSLionel Sambuc AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1924f4a2713aSLionel Sambuc if (A)
1925f4a2713aSLionel Sambuc WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
1926f4a2713aSLionel Sambuc }
AddMemberRef(const FieldDecl * D,SourceLocation L)1927f4a2713aSLionel Sambuc void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
1928f4a2713aSLionel Sambuc if (D)
1929f4a2713aSLionel Sambuc WL.push_back(MemberRefVisit(D, L, Parent));
1930f4a2713aSLionel Sambuc }
AddTypeLoc(TypeSourceInfo * TI)1931f4a2713aSLionel Sambuc void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1932f4a2713aSLionel Sambuc if (TI)
1933f4a2713aSLionel Sambuc WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1934f4a2713aSLionel Sambuc }
EnqueueChildren(const Stmt * S)1935f4a2713aSLionel Sambuc void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
1936f4a2713aSLionel Sambuc unsigned size = WL.size();
1937f4a2713aSLionel Sambuc for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
1938f4a2713aSLionel Sambuc AddStmt(*Child);
1939f4a2713aSLionel Sambuc }
1940f4a2713aSLionel Sambuc if (size == WL.size())
1941f4a2713aSLionel Sambuc return;
1942f4a2713aSLionel Sambuc // Now reverse the entries we just added. This will match the DFS
1943f4a2713aSLionel Sambuc // ordering performed by the worklist.
1944f4a2713aSLionel Sambuc VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1945f4a2713aSLionel Sambuc std::reverse(I, E);
1946f4a2713aSLionel Sambuc }
1947f4a2713aSLionel Sambuc namespace {
1948f4a2713aSLionel Sambuc class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1949f4a2713aSLionel Sambuc EnqueueVisitor *Visitor;
1950f4a2713aSLionel Sambuc /// \brief Process clauses with list of variables.
1951f4a2713aSLionel Sambuc template <typename T>
1952f4a2713aSLionel Sambuc void VisitOMPClauseList(T *Node);
1953f4a2713aSLionel Sambuc public:
OMPClauseEnqueue(EnqueueVisitor * Visitor)1954f4a2713aSLionel Sambuc OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1955f4a2713aSLionel Sambuc #define OPENMP_CLAUSE(Name, Class) \
1956f4a2713aSLionel Sambuc void Visit##Class(const Class *C);
1957f4a2713aSLionel Sambuc #include "clang/Basic/OpenMPKinds.def"
1958f4a2713aSLionel Sambuc };
1959f4a2713aSLionel Sambuc
VisitOMPIfClause(const OMPIfClause * C)1960*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1961*0a6a1f1dSLionel Sambuc Visitor->AddStmt(C->getCondition());
1962*0a6a1f1dSLionel Sambuc }
1963*0a6a1f1dSLionel Sambuc
VisitOMPFinalClause(const OMPFinalClause * C)1964*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1965*0a6a1f1dSLionel Sambuc Visitor->AddStmt(C->getCondition());
1966*0a6a1f1dSLionel Sambuc }
1967*0a6a1f1dSLionel Sambuc
VisitOMPNumThreadsClause(const OMPNumThreadsClause * C)1968*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1969*0a6a1f1dSLionel Sambuc Visitor->AddStmt(C->getNumThreads());
1970*0a6a1f1dSLionel Sambuc }
1971*0a6a1f1dSLionel Sambuc
VisitOMPSafelenClause(const OMPSafelenClause * C)1972*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1973*0a6a1f1dSLionel Sambuc Visitor->AddStmt(C->getSafelen());
1974*0a6a1f1dSLionel Sambuc }
1975*0a6a1f1dSLionel Sambuc
VisitOMPCollapseClause(const OMPCollapseClause * C)1976*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1977*0a6a1f1dSLionel Sambuc Visitor->AddStmt(C->getNumForLoops());
1978*0a6a1f1dSLionel Sambuc }
1979*0a6a1f1dSLionel Sambuc
VisitOMPDefaultClause(const OMPDefaultClause * C)1980f4a2713aSLionel Sambuc void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
1981f4a2713aSLionel Sambuc
VisitOMPProcBindClause(const OMPProcBindClause * C)1982*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1983*0a6a1f1dSLionel Sambuc
VisitOMPScheduleClause(const OMPScheduleClause * C)1984*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1985*0a6a1f1dSLionel Sambuc Visitor->AddStmt(C->getChunkSize());
1986*0a6a1f1dSLionel Sambuc }
1987*0a6a1f1dSLionel Sambuc
VisitOMPOrderedClause(const OMPOrderedClause *)1988*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1989*0a6a1f1dSLionel Sambuc
VisitOMPNowaitClause(const OMPNowaitClause *)1990*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1991*0a6a1f1dSLionel Sambuc
VisitOMPUntiedClause(const OMPUntiedClause *)1992*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1993*0a6a1f1dSLionel Sambuc
VisitOMPMergeableClause(const OMPMergeableClause *)1994*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1995*0a6a1f1dSLionel Sambuc
VisitOMPReadClause(const OMPReadClause *)1996*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1997*0a6a1f1dSLionel Sambuc
VisitOMPWriteClause(const OMPWriteClause *)1998*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1999*0a6a1f1dSLionel Sambuc
VisitOMPUpdateClause(const OMPUpdateClause *)2000*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2001*0a6a1f1dSLionel Sambuc
VisitOMPCaptureClause(const OMPCaptureClause *)2002*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2003*0a6a1f1dSLionel Sambuc
VisitOMPSeqCstClause(const OMPSeqCstClause *)2004*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2005*0a6a1f1dSLionel Sambuc
2006f4a2713aSLionel Sambuc template<typename T>
VisitOMPClauseList(T * Node)2007f4a2713aSLionel Sambuc void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
2008*0a6a1f1dSLionel Sambuc for (const auto *I : Node->varlists()) {
2009*0a6a1f1dSLionel Sambuc Visitor->AddStmt(I);
2010*0a6a1f1dSLionel Sambuc }
2011f4a2713aSLionel Sambuc }
2012f4a2713aSLionel Sambuc
VisitOMPPrivateClause(const OMPPrivateClause * C)2013f4a2713aSLionel Sambuc void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
2014f4a2713aSLionel Sambuc VisitOMPClauseList(C);
2015*0a6a1f1dSLionel Sambuc for (const auto *E : C->private_copies()) {
2016*0a6a1f1dSLionel Sambuc Visitor->AddStmt(E);
2017*0a6a1f1dSLionel Sambuc }
2018f4a2713aSLionel Sambuc }
VisitOMPFirstprivateClause(const OMPFirstprivateClause * C)2019f4a2713aSLionel Sambuc void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2020f4a2713aSLionel Sambuc const OMPFirstprivateClause *C) {
2021f4a2713aSLionel Sambuc VisitOMPClauseList(C);
2022f4a2713aSLionel Sambuc }
VisitOMPLastprivateClause(const OMPLastprivateClause * C)2023*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPLastprivateClause(
2024*0a6a1f1dSLionel Sambuc const OMPLastprivateClause *C) {
2025*0a6a1f1dSLionel Sambuc VisitOMPClauseList(C);
2026*0a6a1f1dSLionel Sambuc }
VisitOMPSharedClause(const OMPSharedClause * C)2027f4a2713aSLionel Sambuc void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
2028f4a2713aSLionel Sambuc VisitOMPClauseList(C);
2029f4a2713aSLionel Sambuc }
VisitOMPReductionClause(const OMPReductionClause * C)2030*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2031*0a6a1f1dSLionel Sambuc VisitOMPClauseList(C);
2032*0a6a1f1dSLionel Sambuc }
VisitOMPLinearClause(const OMPLinearClause * C)2033*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2034*0a6a1f1dSLionel Sambuc VisitOMPClauseList(C);
2035*0a6a1f1dSLionel Sambuc Visitor->AddStmt(C->getStep());
2036*0a6a1f1dSLionel Sambuc }
VisitOMPAlignedClause(const OMPAlignedClause * C)2037*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2038*0a6a1f1dSLionel Sambuc VisitOMPClauseList(C);
2039*0a6a1f1dSLionel Sambuc Visitor->AddStmt(C->getAlignment());
2040*0a6a1f1dSLionel Sambuc }
VisitOMPCopyinClause(const OMPCopyinClause * C)2041*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2042*0a6a1f1dSLionel Sambuc VisitOMPClauseList(C);
2043*0a6a1f1dSLionel Sambuc }
2044*0a6a1f1dSLionel Sambuc void
VisitOMPCopyprivateClause(const OMPCopyprivateClause * C)2045*0a6a1f1dSLionel Sambuc OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2046*0a6a1f1dSLionel Sambuc VisitOMPClauseList(C);
2047*0a6a1f1dSLionel Sambuc }
VisitOMPFlushClause(const OMPFlushClause * C)2048*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2049*0a6a1f1dSLionel Sambuc VisitOMPClauseList(C);
2050*0a6a1f1dSLionel Sambuc }
2051f4a2713aSLionel Sambuc }
2052f4a2713aSLionel Sambuc
EnqueueChildren(const OMPClause * S)2053f4a2713aSLionel Sambuc void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2054f4a2713aSLionel Sambuc unsigned size = WL.size();
2055f4a2713aSLionel Sambuc OMPClauseEnqueue Visitor(this);
2056f4a2713aSLionel Sambuc Visitor.Visit(S);
2057f4a2713aSLionel Sambuc if (size == WL.size())
2058f4a2713aSLionel Sambuc return;
2059f4a2713aSLionel Sambuc // Now reverse the entries we just added. This will match the DFS
2060f4a2713aSLionel Sambuc // ordering performed by the worklist.
2061f4a2713aSLionel Sambuc VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2062f4a2713aSLionel Sambuc std::reverse(I, E);
2063f4a2713aSLionel Sambuc }
VisitAddrLabelExpr(const AddrLabelExpr * E)2064f4a2713aSLionel Sambuc void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
2065f4a2713aSLionel Sambuc WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2066f4a2713aSLionel Sambuc }
VisitBlockExpr(const BlockExpr * B)2067f4a2713aSLionel Sambuc void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
2068f4a2713aSLionel Sambuc AddDecl(B->getBlockDecl());
2069f4a2713aSLionel Sambuc }
VisitCompoundLiteralExpr(const CompoundLiteralExpr * E)2070f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
2071f4a2713aSLionel Sambuc EnqueueChildren(E);
2072f4a2713aSLionel Sambuc AddTypeLoc(E->getTypeSourceInfo());
2073f4a2713aSLionel Sambuc }
VisitCompoundStmt(const CompoundStmt * S)2074f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2075f4a2713aSLionel Sambuc for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
2076f4a2713aSLionel Sambuc E = S->body_rend(); I != E; ++I) {
2077f4a2713aSLionel Sambuc AddStmt(*I);
2078f4a2713aSLionel Sambuc }
2079f4a2713aSLionel Sambuc }
2080f4a2713aSLionel Sambuc void EnqueueVisitor::
VisitMSDependentExistsStmt(const MSDependentExistsStmt * S)2081f4a2713aSLionel Sambuc VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
2082f4a2713aSLionel Sambuc AddStmt(S->getSubStmt());
2083f4a2713aSLionel Sambuc AddDeclarationNameInfo(S);
2084f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2085f4a2713aSLionel Sambuc AddNestedNameSpecifierLoc(QualifierLoc);
2086f4a2713aSLionel Sambuc }
2087f4a2713aSLionel Sambuc
2088f4a2713aSLionel Sambuc void EnqueueVisitor::
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr * E)2089f4a2713aSLionel Sambuc VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
2090f4a2713aSLionel Sambuc AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2091f4a2713aSLionel Sambuc AddDeclarationNameInfo(E);
2092f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2093f4a2713aSLionel Sambuc AddNestedNameSpecifierLoc(QualifierLoc);
2094f4a2713aSLionel Sambuc if (!E->isImplicitAccess())
2095f4a2713aSLionel Sambuc AddStmt(E->getBase());
2096f4a2713aSLionel Sambuc }
VisitCXXNewExpr(const CXXNewExpr * E)2097f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
2098f4a2713aSLionel Sambuc // Enqueue the initializer , if any.
2099f4a2713aSLionel Sambuc AddStmt(E->getInitializer());
2100f4a2713aSLionel Sambuc // Enqueue the array size, if any.
2101f4a2713aSLionel Sambuc AddStmt(E->getArraySize());
2102f4a2713aSLionel Sambuc // Enqueue the allocated type.
2103f4a2713aSLionel Sambuc AddTypeLoc(E->getAllocatedTypeSourceInfo());
2104f4a2713aSLionel Sambuc // Enqueue the placement arguments.
2105f4a2713aSLionel Sambuc for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2106f4a2713aSLionel Sambuc AddStmt(E->getPlacementArg(I-1));
2107f4a2713aSLionel Sambuc }
VisitCXXOperatorCallExpr(const CXXOperatorCallExpr * CE)2108f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
2109f4a2713aSLionel Sambuc for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2110f4a2713aSLionel Sambuc AddStmt(CE->getArg(I-1));
2111f4a2713aSLionel Sambuc AddStmt(CE->getCallee());
2112f4a2713aSLionel Sambuc AddStmt(CE->getArg(0));
2113f4a2713aSLionel Sambuc }
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)2114f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2115f4a2713aSLionel Sambuc const CXXPseudoDestructorExpr *E) {
2116f4a2713aSLionel Sambuc // Visit the name of the type being destroyed.
2117f4a2713aSLionel Sambuc AddTypeLoc(E->getDestroyedTypeInfo());
2118f4a2713aSLionel Sambuc // Visit the scope type that looks disturbingly like the nested-name-specifier
2119f4a2713aSLionel Sambuc // but isn't.
2120f4a2713aSLionel Sambuc AddTypeLoc(E->getScopeTypeInfo());
2121f4a2713aSLionel Sambuc // Visit the nested-name-specifier.
2122f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2123f4a2713aSLionel Sambuc AddNestedNameSpecifierLoc(QualifierLoc);
2124f4a2713aSLionel Sambuc // Visit base expression.
2125f4a2713aSLionel Sambuc AddStmt(E->getBase());
2126f4a2713aSLionel Sambuc }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)2127f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2128f4a2713aSLionel Sambuc const CXXScalarValueInitExpr *E) {
2129f4a2713aSLionel Sambuc AddTypeLoc(E->getTypeSourceInfo());
2130f4a2713aSLionel Sambuc }
VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr * E)2131f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2132f4a2713aSLionel Sambuc const CXXTemporaryObjectExpr *E) {
2133f4a2713aSLionel Sambuc EnqueueChildren(E);
2134f4a2713aSLionel Sambuc AddTypeLoc(E->getTypeSourceInfo());
2135f4a2713aSLionel Sambuc }
VisitCXXTypeidExpr(const CXXTypeidExpr * E)2136f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
2137f4a2713aSLionel Sambuc EnqueueChildren(E);
2138f4a2713aSLionel Sambuc if (E->isTypeOperand())
2139f4a2713aSLionel Sambuc AddTypeLoc(E->getTypeOperandSourceInfo());
2140f4a2713aSLionel Sambuc }
2141f4a2713aSLionel Sambuc
VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr * E)2142f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2143f4a2713aSLionel Sambuc const CXXUnresolvedConstructExpr *E) {
2144f4a2713aSLionel Sambuc EnqueueChildren(E);
2145f4a2713aSLionel Sambuc AddTypeLoc(E->getTypeSourceInfo());
2146f4a2713aSLionel Sambuc }
VisitCXXUuidofExpr(const CXXUuidofExpr * E)2147f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
2148f4a2713aSLionel Sambuc EnqueueChildren(E);
2149f4a2713aSLionel Sambuc if (E->isTypeOperand())
2150f4a2713aSLionel Sambuc AddTypeLoc(E->getTypeOperandSourceInfo());
2151f4a2713aSLionel Sambuc }
2152f4a2713aSLionel Sambuc
VisitCXXCatchStmt(const CXXCatchStmt * S)2153f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
2154f4a2713aSLionel Sambuc EnqueueChildren(S);
2155f4a2713aSLionel Sambuc AddDecl(S->getExceptionDecl());
2156f4a2713aSLionel Sambuc }
2157f4a2713aSLionel Sambuc
VisitCXXForRangeStmt(const CXXForRangeStmt * S)2158*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
2159*0a6a1f1dSLionel Sambuc AddStmt(S->getBody());
2160*0a6a1f1dSLionel Sambuc AddStmt(S->getRangeInit());
2161*0a6a1f1dSLionel Sambuc AddDecl(S->getLoopVariable());
2162*0a6a1f1dSLionel Sambuc }
2163*0a6a1f1dSLionel Sambuc
VisitDeclRefExpr(const DeclRefExpr * DR)2164f4a2713aSLionel Sambuc void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
2165f4a2713aSLionel Sambuc if (DR->hasExplicitTemplateArgs()) {
2166f4a2713aSLionel Sambuc AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2167f4a2713aSLionel Sambuc }
2168f4a2713aSLionel Sambuc WL.push_back(DeclRefExprParts(DR, Parent));
2169f4a2713aSLionel Sambuc }
VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr * E)2170f4a2713aSLionel Sambuc void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2171f4a2713aSLionel Sambuc const DependentScopeDeclRefExpr *E) {
2172f4a2713aSLionel Sambuc AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2173f4a2713aSLionel Sambuc AddDeclarationNameInfo(E);
2174f4a2713aSLionel Sambuc AddNestedNameSpecifierLoc(E->getQualifierLoc());
2175f4a2713aSLionel Sambuc }
VisitDeclStmt(const DeclStmt * S)2176f4a2713aSLionel Sambuc void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
2177f4a2713aSLionel Sambuc unsigned size = WL.size();
2178f4a2713aSLionel Sambuc bool isFirst = true;
2179*0a6a1f1dSLionel Sambuc for (const auto *D : S->decls()) {
2180*0a6a1f1dSLionel Sambuc AddDecl(D, isFirst);
2181f4a2713aSLionel Sambuc isFirst = false;
2182f4a2713aSLionel Sambuc }
2183f4a2713aSLionel Sambuc if (size == WL.size())
2184f4a2713aSLionel Sambuc return;
2185f4a2713aSLionel Sambuc // Now reverse the entries we just added. This will match the DFS
2186f4a2713aSLionel Sambuc // ordering performed by the worklist.
2187f4a2713aSLionel Sambuc VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2188f4a2713aSLionel Sambuc std::reverse(I, E);
2189f4a2713aSLionel Sambuc }
VisitDesignatedInitExpr(const DesignatedInitExpr * E)2190f4a2713aSLionel Sambuc void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
2191f4a2713aSLionel Sambuc AddStmt(E->getInit());
2192f4a2713aSLionel Sambuc for (DesignatedInitExpr::const_reverse_designators_iterator
2193f4a2713aSLionel Sambuc D = E->designators_rbegin(), DEnd = E->designators_rend();
2194f4a2713aSLionel Sambuc D != DEnd; ++D) {
2195f4a2713aSLionel Sambuc if (D->isFieldDesignator()) {
2196f4a2713aSLionel Sambuc if (FieldDecl *Field = D->getField())
2197f4a2713aSLionel Sambuc AddMemberRef(Field, D->getFieldLoc());
2198f4a2713aSLionel Sambuc continue;
2199f4a2713aSLionel Sambuc }
2200f4a2713aSLionel Sambuc if (D->isArrayDesignator()) {
2201f4a2713aSLionel Sambuc AddStmt(E->getArrayIndex(*D));
2202f4a2713aSLionel Sambuc continue;
2203f4a2713aSLionel Sambuc }
2204f4a2713aSLionel Sambuc assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2205f4a2713aSLionel Sambuc AddStmt(E->getArrayRangeEnd(*D));
2206f4a2713aSLionel Sambuc AddStmt(E->getArrayRangeStart(*D));
2207f4a2713aSLionel Sambuc }
2208f4a2713aSLionel Sambuc }
VisitExplicitCastExpr(const ExplicitCastExpr * E)2209f4a2713aSLionel Sambuc void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
2210f4a2713aSLionel Sambuc EnqueueChildren(E);
2211f4a2713aSLionel Sambuc AddTypeLoc(E->getTypeInfoAsWritten());
2212f4a2713aSLionel Sambuc }
VisitForStmt(const ForStmt * FS)2213f4a2713aSLionel Sambuc void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
2214f4a2713aSLionel Sambuc AddStmt(FS->getBody());
2215f4a2713aSLionel Sambuc AddStmt(FS->getInc());
2216f4a2713aSLionel Sambuc AddStmt(FS->getCond());
2217f4a2713aSLionel Sambuc AddDecl(FS->getConditionVariable());
2218f4a2713aSLionel Sambuc AddStmt(FS->getInit());
2219f4a2713aSLionel Sambuc }
VisitGotoStmt(const GotoStmt * GS)2220f4a2713aSLionel Sambuc void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
2221f4a2713aSLionel Sambuc WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2222f4a2713aSLionel Sambuc }
VisitIfStmt(const IfStmt * If)2223f4a2713aSLionel Sambuc void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
2224f4a2713aSLionel Sambuc AddStmt(If->getElse());
2225f4a2713aSLionel Sambuc AddStmt(If->getThen());
2226f4a2713aSLionel Sambuc AddStmt(If->getCond());
2227f4a2713aSLionel Sambuc AddDecl(If->getConditionVariable());
2228f4a2713aSLionel Sambuc }
VisitInitListExpr(const InitListExpr * IE)2229f4a2713aSLionel Sambuc void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
2230f4a2713aSLionel Sambuc // We care about the syntactic form of the initializer list, only.
2231f4a2713aSLionel Sambuc if (InitListExpr *Syntactic = IE->getSyntacticForm())
2232f4a2713aSLionel Sambuc IE = Syntactic;
2233f4a2713aSLionel Sambuc EnqueueChildren(IE);
2234f4a2713aSLionel Sambuc }
VisitMemberExpr(const MemberExpr * M)2235f4a2713aSLionel Sambuc void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
2236f4a2713aSLionel Sambuc WL.push_back(MemberExprParts(M, Parent));
2237f4a2713aSLionel Sambuc
2238f4a2713aSLionel Sambuc // If the base of the member access expression is an implicit 'this', don't
2239f4a2713aSLionel Sambuc // visit it.
2240f4a2713aSLionel Sambuc // FIXME: If we ever want to show these implicit accesses, this will be
2241f4a2713aSLionel Sambuc // unfortunate. However, clang_getCursor() relies on this behavior.
2242f4a2713aSLionel Sambuc if (!M->isImplicitAccess())
2243f4a2713aSLionel Sambuc AddStmt(M->getBase());
2244f4a2713aSLionel Sambuc }
VisitObjCEncodeExpr(const ObjCEncodeExpr * E)2245f4a2713aSLionel Sambuc void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
2246f4a2713aSLionel Sambuc AddTypeLoc(E->getEncodedTypeSourceInfo());
2247f4a2713aSLionel Sambuc }
VisitObjCMessageExpr(const ObjCMessageExpr * M)2248f4a2713aSLionel Sambuc void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
2249f4a2713aSLionel Sambuc EnqueueChildren(M);
2250f4a2713aSLionel Sambuc AddTypeLoc(M->getClassReceiverTypeInfo());
2251f4a2713aSLionel Sambuc }
VisitOffsetOfExpr(const OffsetOfExpr * E)2252f4a2713aSLionel Sambuc void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
2253f4a2713aSLionel Sambuc // Visit the components of the offsetof expression.
2254f4a2713aSLionel Sambuc for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2255f4a2713aSLionel Sambuc typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2256f4a2713aSLionel Sambuc const OffsetOfNode &Node = E->getComponent(I-1);
2257f4a2713aSLionel Sambuc switch (Node.getKind()) {
2258f4a2713aSLionel Sambuc case OffsetOfNode::Array:
2259f4a2713aSLionel Sambuc AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2260f4a2713aSLionel Sambuc break;
2261f4a2713aSLionel Sambuc case OffsetOfNode::Field:
2262f4a2713aSLionel Sambuc AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2263f4a2713aSLionel Sambuc break;
2264f4a2713aSLionel Sambuc case OffsetOfNode::Identifier:
2265f4a2713aSLionel Sambuc case OffsetOfNode::Base:
2266f4a2713aSLionel Sambuc continue;
2267f4a2713aSLionel Sambuc }
2268f4a2713aSLionel Sambuc }
2269f4a2713aSLionel Sambuc // Visit the type into which we're computing the offset.
2270f4a2713aSLionel Sambuc AddTypeLoc(E->getTypeSourceInfo());
2271f4a2713aSLionel Sambuc }
VisitOverloadExpr(const OverloadExpr * E)2272f4a2713aSLionel Sambuc void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
2273f4a2713aSLionel Sambuc AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2274f4a2713aSLionel Sambuc WL.push_back(OverloadExprParts(E, Parent));
2275f4a2713aSLionel Sambuc }
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)2276f4a2713aSLionel Sambuc void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2277f4a2713aSLionel Sambuc const UnaryExprOrTypeTraitExpr *E) {
2278f4a2713aSLionel Sambuc EnqueueChildren(E);
2279f4a2713aSLionel Sambuc if (E->isArgumentType())
2280f4a2713aSLionel Sambuc AddTypeLoc(E->getArgumentTypeInfo());
2281f4a2713aSLionel Sambuc }
VisitStmt(const Stmt * S)2282f4a2713aSLionel Sambuc void EnqueueVisitor::VisitStmt(const Stmt *S) {
2283f4a2713aSLionel Sambuc EnqueueChildren(S);
2284f4a2713aSLionel Sambuc }
VisitSwitchStmt(const SwitchStmt * S)2285f4a2713aSLionel Sambuc void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
2286f4a2713aSLionel Sambuc AddStmt(S->getBody());
2287f4a2713aSLionel Sambuc AddStmt(S->getCond());
2288f4a2713aSLionel Sambuc AddDecl(S->getConditionVariable());
2289f4a2713aSLionel Sambuc }
2290f4a2713aSLionel Sambuc
VisitWhileStmt(const WhileStmt * W)2291f4a2713aSLionel Sambuc void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
2292f4a2713aSLionel Sambuc AddStmt(W->getBody());
2293f4a2713aSLionel Sambuc AddStmt(W->getCond());
2294f4a2713aSLionel Sambuc AddDecl(W->getConditionVariable());
2295f4a2713aSLionel Sambuc }
2296f4a2713aSLionel Sambuc
VisitTypeTraitExpr(const TypeTraitExpr * E)2297f4a2713aSLionel Sambuc void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
2298f4a2713aSLionel Sambuc for (unsigned I = E->getNumArgs(); I > 0; --I)
2299f4a2713aSLionel Sambuc AddTypeLoc(E->getArg(I-1));
2300f4a2713aSLionel Sambuc }
2301f4a2713aSLionel Sambuc
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)2302f4a2713aSLionel Sambuc void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
2303f4a2713aSLionel Sambuc AddTypeLoc(E->getQueriedTypeSourceInfo());
2304f4a2713aSLionel Sambuc }
2305f4a2713aSLionel Sambuc
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)2306f4a2713aSLionel Sambuc void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
2307f4a2713aSLionel Sambuc EnqueueChildren(E);
2308f4a2713aSLionel Sambuc }
2309f4a2713aSLionel Sambuc
VisitUnresolvedMemberExpr(const UnresolvedMemberExpr * U)2310f4a2713aSLionel Sambuc void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
2311f4a2713aSLionel Sambuc VisitOverloadExpr(U);
2312f4a2713aSLionel Sambuc if (!U->isImplicitAccess())
2313f4a2713aSLionel Sambuc AddStmt(U->getBase());
2314f4a2713aSLionel Sambuc }
VisitVAArgExpr(const VAArgExpr * E)2315f4a2713aSLionel Sambuc void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
2316f4a2713aSLionel Sambuc AddStmt(E->getSubExpr());
2317f4a2713aSLionel Sambuc AddTypeLoc(E->getWrittenTypeInfo());
2318f4a2713aSLionel Sambuc }
VisitSizeOfPackExpr(const SizeOfPackExpr * E)2319f4a2713aSLionel Sambuc void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
2320f4a2713aSLionel Sambuc WL.push_back(SizeOfPackExprParts(E, Parent));
2321f4a2713aSLionel Sambuc }
VisitOpaqueValueExpr(const OpaqueValueExpr * E)2322f4a2713aSLionel Sambuc void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2323f4a2713aSLionel Sambuc // If the opaque value has a source expression, just transparently
2324f4a2713aSLionel Sambuc // visit that. This is useful for (e.g.) pseudo-object expressions.
2325f4a2713aSLionel Sambuc if (Expr *SourceExpr = E->getSourceExpr())
2326f4a2713aSLionel Sambuc return Visit(SourceExpr);
2327f4a2713aSLionel Sambuc }
VisitLambdaExpr(const LambdaExpr * E)2328f4a2713aSLionel Sambuc void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
2329f4a2713aSLionel Sambuc AddStmt(E->getBody());
2330f4a2713aSLionel Sambuc WL.push_back(LambdaExprParts(E, Parent));
2331f4a2713aSLionel Sambuc }
VisitPseudoObjectExpr(const PseudoObjectExpr * E)2332f4a2713aSLionel Sambuc void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
2333f4a2713aSLionel Sambuc // Treat the expression like its syntactic form.
2334f4a2713aSLionel Sambuc Visit(E->getSyntacticForm());
2335f4a2713aSLionel Sambuc }
2336f4a2713aSLionel Sambuc
VisitOMPExecutableDirective(const OMPExecutableDirective * D)2337f4a2713aSLionel Sambuc void EnqueueVisitor::VisitOMPExecutableDirective(
2338f4a2713aSLionel Sambuc const OMPExecutableDirective *D) {
2339f4a2713aSLionel Sambuc EnqueueChildren(D);
2340f4a2713aSLionel Sambuc for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2341f4a2713aSLionel Sambuc E = D->clauses().end();
2342f4a2713aSLionel Sambuc I != E; ++I)
2343f4a2713aSLionel Sambuc EnqueueChildren(*I);
2344f4a2713aSLionel Sambuc }
2345f4a2713aSLionel Sambuc
VisitOMPLoopDirective(const OMPLoopDirective * D)2346*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2347*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2348*0a6a1f1dSLionel Sambuc }
2349*0a6a1f1dSLionel Sambuc
VisitOMPParallelDirective(const OMPParallelDirective * D)2350f4a2713aSLionel Sambuc void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2351f4a2713aSLionel Sambuc VisitOMPExecutableDirective(D);
2352f4a2713aSLionel Sambuc }
2353f4a2713aSLionel Sambuc
VisitOMPSimdDirective(const OMPSimdDirective * D)2354*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2355*0a6a1f1dSLionel Sambuc VisitOMPLoopDirective(D);
2356*0a6a1f1dSLionel Sambuc }
2357*0a6a1f1dSLionel Sambuc
VisitOMPForDirective(const OMPForDirective * D)2358*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2359*0a6a1f1dSLionel Sambuc VisitOMPLoopDirective(D);
2360*0a6a1f1dSLionel Sambuc }
2361*0a6a1f1dSLionel Sambuc
VisitOMPForSimdDirective(const OMPForSimdDirective * D)2362*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2363*0a6a1f1dSLionel Sambuc VisitOMPLoopDirective(D);
2364*0a6a1f1dSLionel Sambuc }
2365*0a6a1f1dSLionel Sambuc
VisitOMPSectionsDirective(const OMPSectionsDirective * D)2366*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2367*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2368*0a6a1f1dSLionel Sambuc }
2369*0a6a1f1dSLionel Sambuc
VisitOMPSectionDirective(const OMPSectionDirective * D)2370*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2371*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2372*0a6a1f1dSLionel Sambuc }
2373*0a6a1f1dSLionel Sambuc
VisitOMPSingleDirective(const OMPSingleDirective * D)2374*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2375*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2376*0a6a1f1dSLionel Sambuc }
2377*0a6a1f1dSLionel Sambuc
VisitOMPMasterDirective(const OMPMasterDirective * D)2378*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2379*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2380*0a6a1f1dSLionel Sambuc }
2381*0a6a1f1dSLionel Sambuc
VisitOMPCriticalDirective(const OMPCriticalDirective * D)2382*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2383*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2384*0a6a1f1dSLionel Sambuc AddDeclarationNameInfo(D);
2385*0a6a1f1dSLionel Sambuc }
2386*0a6a1f1dSLionel Sambuc
2387*0a6a1f1dSLionel Sambuc void
VisitOMPParallelForDirective(const OMPParallelForDirective * D)2388*0a6a1f1dSLionel Sambuc EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2389*0a6a1f1dSLionel Sambuc VisitOMPLoopDirective(D);
2390*0a6a1f1dSLionel Sambuc }
2391*0a6a1f1dSLionel Sambuc
VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective * D)2392*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2393*0a6a1f1dSLionel Sambuc const OMPParallelForSimdDirective *D) {
2394*0a6a1f1dSLionel Sambuc VisitOMPLoopDirective(D);
2395*0a6a1f1dSLionel Sambuc }
2396*0a6a1f1dSLionel Sambuc
VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective * D)2397*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2398*0a6a1f1dSLionel Sambuc const OMPParallelSectionsDirective *D) {
2399*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2400*0a6a1f1dSLionel Sambuc }
2401*0a6a1f1dSLionel Sambuc
VisitOMPTaskDirective(const OMPTaskDirective * D)2402*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2403*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2404*0a6a1f1dSLionel Sambuc }
2405*0a6a1f1dSLionel Sambuc
2406*0a6a1f1dSLionel Sambuc void
VisitOMPTaskyieldDirective(const OMPTaskyieldDirective * D)2407*0a6a1f1dSLionel Sambuc EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2408*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2409*0a6a1f1dSLionel Sambuc }
2410*0a6a1f1dSLionel Sambuc
VisitOMPBarrierDirective(const OMPBarrierDirective * D)2411*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2412*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2413*0a6a1f1dSLionel Sambuc }
2414*0a6a1f1dSLionel Sambuc
VisitOMPTaskwaitDirective(const OMPTaskwaitDirective * D)2415*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2416*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2417*0a6a1f1dSLionel Sambuc }
2418*0a6a1f1dSLionel Sambuc
VisitOMPFlushDirective(const OMPFlushDirective * D)2419*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2420*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2421*0a6a1f1dSLionel Sambuc }
2422*0a6a1f1dSLionel Sambuc
VisitOMPOrderedDirective(const OMPOrderedDirective * D)2423*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2424*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2425*0a6a1f1dSLionel Sambuc }
2426*0a6a1f1dSLionel Sambuc
VisitOMPAtomicDirective(const OMPAtomicDirective * D)2427*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2428*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2429*0a6a1f1dSLionel Sambuc }
2430*0a6a1f1dSLionel Sambuc
VisitOMPTargetDirective(const OMPTargetDirective * D)2431*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2432*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2433*0a6a1f1dSLionel Sambuc }
2434*0a6a1f1dSLionel Sambuc
VisitOMPTeamsDirective(const OMPTeamsDirective * D)2435*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2436*0a6a1f1dSLionel Sambuc VisitOMPExecutableDirective(D);
2437*0a6a1f1dSLionel Sambuc }
2438*0a6a1f1dSLionel Sambuc
EnqueueWorkList(VisitorWorkList & WL,const Stmt * S)2439f4a2713aSLionel Sambuc void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
2440f4a2713aSLionel Sambuc EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2441f4a2713aSLionel Sambuc }
2442f4a2713aSLionel Sambuc
IsInRegionOfInterest(CXCursor C)2443f4a2713aSLionel Sambuc bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2444f4a2713aSLionel Sambuc if (RegionOfInterest.isValid()) {
2445f4a2713aSLionel Sambuc SourceRange Range = getRawCursorExtent(C);
2446f4a2713aSLionel Sambuc if (Range.isInvalid() || CompareRegionOfInterest(Range))
2447f4a2713aSLionel Sambuc return false;
2448f4a2713aSLionel Sambuc }
2449f4a2713aSLionel Sambuc return true;
2450f4a2713aSLionel Sambuc }
2451f4a2713aSLionel Sambuc
RunVisitorWorkList(VisitorWorkList & WL)2452f4a2713aSLionel Sambuc bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2453f4a2713aSLionel Sambuc while (!WL.empty()) {
2454f4a2713aSLionel Sambuc // Dequeue the worklist item.
2455f4a2713aSLionel Sambuc VisitorJob LI = WL.pop_back_val();
2456f4a2713aSLionel Sambuc
2457f4a2713aSLionel Sambuc // Set the Parent field, then back to its old value once we're done.
2458f4a2713aSLionel Sambuc SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2459f4a2713aSLionel Sambuc
2460f4a2713aSLionel Sambuc switch (LI.getKind()) {
2461f4a2713aSLionel Sambuc case VisitorJob::DeclVisitKind: {
2462f4a2713aSLionel Sambuc const Decl *D = cast<DeclVisit>(&LI)->get();
2463f4a2713aSLionel Sambuc if (!D)
2464f4a2713aSLionel Sambuc continue;
2465f4a2713aSLionel Sambuc
2466f4a2713aSLionel Sambuc // For now, perform default visitation for Decls.
2467f4a2713aSLionel Sambuc if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2468f4a2713aSLionel Sambuc cast<DeclVisit>(&LI)->isFirst())))
2469f4a2713aSLionel Sambuc return true;
2470f4a2713aSLionel Sambuc
2471f4a2713aSLionel Sambuc continue;
2472f4a2713aSLionel Sambuc }
2473f4a2713aSLionel Sambuc case VisitorJob::ExplicitTemplateArgsVisitKind: {
2474f4a2713aSLionel Sambuc const ASTTemplateArgumentListInfo *ArgList =
2475f4a2713aSLionel Sambuc cast<ExplicitTemplateArgsVisit>(&LI)->get();
2476f4a2713aSLionel Sambuc for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2477f4a2713aSLionel Sambuc *ArgEnd = Arg + ArgList->NumTemplateArgs;
2478f4a2713aSLionel Sambuc Arg != ArgEnd; ++Arg) {
2479f4a2713aSLionel Sambuc if (VisitTemplateArgumentLoc(*Arg))
2480f4a2713aSLionel Sambuc return true;
2481f4a2713aSLionel Sambuc }
2482f4a2713aSLionel Sambuc continue;
2483f4a2713aSLionel Sambuc }
2484f4a2713aSLionel Sambuc case VisitorJob::TypeLocVisitKind: {
2485f4a2713aSLionel Sambuc // Perform default visitation for TypeLocs.
2486f4a2713aSLionel Sambuc if (Visit(cast<TypeLocVisit>(&LI)->get()))
2487f4a2713aSLionel Sambuc return true;
2488f4a2713aSLionel Sambuc continue;
2489f4a2713aSLionel Sambuc }
2490f4a2713aSLionel Sambuc case VisitorJob::LabelRefVisitKind: {
2491f4a2713aSLionel Sambuc const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
2492f4a2713aSLionel Sambuc if (LabelStmt *stmt = LS->getStmt()) {
2493f4a2713aSLionel Sambuc if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2494f4a2713aSLionel Sambuc TU))) {
2495f4a2713aSLionel Sambuc return true;
2496f4a2713aSLionel Sambuc }
2497f4a2713aSLionel Sambuc }
2498f4a2713aSLionel Sambuc continue;
2499f4a2713aSLionel Sambuc }
2500f4a2713aSLionel Sambuc
2501f4a2713aSLionel Sambuc case VisitorJob::NestedNameSpecifierLocVisitKind: {
2502f4a2713aSLionel Sambuc NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2503f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(V->get()))
2504f4a2713aSLionel Sambuc return true;
2505f4a2713aSLionel Sambuc continue;
2506f4a2713aSLionel Sambuc }
2507f4a2713aSLionel Sambuc
2508f4a2713aSLionel Sambuc case VisitorJob::DeclarationNameInfoVisitKind: {
2509f4a2713aSLionel Sambuc if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2510f4a2713aSLionel Sambuc ->get()))
2511f4a2713aSLionel Sambuc return true;
2512f4a2713aSLionel Sambuc continue;
2513f4a2713aSLionel Sambuc }
2514f4a2713aSLionel Sambuc case VisitorJob::MemberRefVisitKind: {
2515f4a2713aSLionel Sambuc MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2516f4a2713aSLionel Sambuc if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2517f4a2713aSLionel Sambuc return true;
2518f4a2713aSLionel Sambuc continue;
2519f4a2713aSLionel Sambuc }
2520f4a2713aSLionel Sambuc case VisitorJob::StmtVisitKind: {
2521f4a2713aSLionel Sambuc const Stmt *S = cast<StmtVisit>(&LI)->get();
2522f4a2713aSLionel Sambuc if (!S)
2523f4a2713aSLionel Sambuc continue;
2524f4a2713aSLionel Sambuc
2525f4a2713aSLionel Sambuc // Update the current cursor.
2526f4a2713aSLionel Sambuc CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2527f4a2713aSLionel Sambuc if (!IsInRegionOfInterest(Cursor))
2528f4a2713aSLionel Sambuc continue;
2529f4a2713aSLionel Sambuc switch (Visitor(Cursor, Parent, ClientData)) {
2530f4a2713aSLionel Sambuc case CXChildVisit_Break: return true;
2531f4a2713aSLionel Sambuc case CXChildVisit_Continue: break;
2532f4a2713aSLionel Sambuc case CXChildVisit_Recurse:
2533f4a2713aSLionel Sambuc if (PostChildrenVisitor)
2534*0a6a1f1dSLionel Sambuc WL.push_back(PostChildrenVisit(nullptr, Cursor));
2535f4a2713aSLionel Sambuc EnqueueWorkList(WL, S);
2536f4a2713aSLionel Sambuc break;
2537f4a2713aSLionel Sambuc }
2538f4a2713aSLionel Sambuc continue;
2539f4a2713aSLionel Sambuc }
2540f4a2713aSLionel Sambuc case VisitorJob::MemberExprPartsKind: {
2541f4a2713aSLionel Sambuc // Handle the other pieces in the MemberExpr besides the base.
2542f4a2713aSLionel Sambuc const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
2543f4a2713aSLionel Sambuc
2544f4a2713aSLionel Sambuc // Visit the nested-name-specifier
2545f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2546f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
2547f4a2713aSLionel Sambuc return true;
2548f4a2713aSLionel Sambuc
2549f4a2713aSLionel Sambuc // Visit the declaration name.
2550f4a2713aSLionel Sambuc if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2551f4a2713aSLionel Sambuc return true;
2552f4a2713aSLionel Sambuc
2553f4a2713aSLionel Sambuc // Visit the explicitly-specified template arguments, if any.
2554f4a2713aSLionel Sambuc if (M->hasExplicitTemplateArgs()) {
2555f4a2713aSLionel Sambuc for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2556f4a2713aSLionel Sambuc *ArgEnd = Arg + M->getNumTemplateArgs();
2557f4a2713aSLionel Sambuc Arg != ArgEnd; ++Arg) {
2558f4a2713aSLionel Sambuc if (VisitTemplateArgumentLoc(*Arg))
2559f4a2713aSLionel Sambuc return true;
2560f4a2713aSLionel Sambuc }
2561f4a2713aSLionel Sambuc }
2562f4a2713aSLionel Sambuc continue;
2563f4a2713aSLionel Sambuc }
2564f4a2713aSLionel Sambuc case VisitorJob::DeclRefExprPartsKind: {
2565f4a2713aSLionel Sambuc const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
2566f4a2713aSLionel Sambuc // Visit nested-name-specifier, if present.
2567f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2568f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
2569f4a2713aSLionel Sambuc return true;
2570f4a2713aSLionel Sambuc // Visit declaration name.
2571f4a2713aSLionel Sambuc if (VisitDeclarationNameInfo(DR->getNameInfo()))
2572f4a2713aSLionel Sambuc return true;
2573f4a2713aSLionel Sambuc continue;
2574f4a2713aSLionel Sambuc }
2575f4a2713aSLionel Sambuc case VisitorJob::OverloadExprPartsKind: {
2576f4a2713aSLionel Sambuc const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
2577f4a2713aSLionel Sambuc // Visit the nested-name-specifier.
2578f4a2713aSLionel Sambuc if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2579f4a2713aSLionel Sambuc if (VisitNestedNameSpecifierLoc(QualifierLoc))
2580f4a2713aSLionel Sambuc return true;
2581f4a2713aSLionel Sambuc // Visit the declaration name.
2582f4a2713aSLionel Sambuc if (VisitDeclarationNameInfo(O->getNameInfo()))
2583f4a2713aSLionel Sambuc return true;
2584f4a2713aSLionel Sambuc // Visit the overloaded declaration reference.
2585f4a2713aSLionel Sambuc if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2586f4a2713aSLionel Sambuc return true;
2587f4a2713aSLionel Sambuc continue;
2588f4a2713aSLionel Sambuc }
2589f4a2713aSLionel Sambuc case VisitorJob::SizeOfPackExprPartsKind: {
2590f4a2713aSLionel Sambuc const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2591f4a2713aSLionel Sambuc NamedDecl *Pack = E->getPack();
2592f4a2713aSLionel Sambuc if (isa<TemplateTypeParmDecl>(Pack)) {
2593f4a2713aSLionel Sambuc if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2594f4a2713aSLionel Sambuc E->getPackLoc(), TU)))
2595f4a2713aSLionel Sambuc return true;
2596f4a2713aSLionel Sambuc
2597f4a2713aSLionel Sambuc continue;
2598f4a2713aSLionel Sambuc }
2599f4a2713aSLionel Sambuc
2600f4a2713aSLionel Sambuc if (isa<TemplateTemplateParmDecl>(Pack)) {
2601f4a2713aSLionel Sambuc if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2602f4a2713aSLionel Sambuc E->getPackLoc(), TU)))
2603f4a2713aSLionel Sambuc return true;
2604f4a2713aSLionel Sambuc
2605f4a2713aSLionel Sambuc continue;
2606f4a2713aSLionel Sambuc }
2607f4a2713aSLionel Sambuc
2608f4a2713aSLionel Sambuc // Non-type template parameter packs and function parameter packs are
2609f4a2713aSLionel Sambuc // treated like DeclRefExpr cursors.
2610f4a2713aSLionel Sambuc continue;
2611f4a2713aSLionel Sambuc }
2612f4a2713aSLionel Sambuc
2613f4a2713aSLionel Sambuc case VisitorJob::LambdaExprPartsKind: {
2614f4a2713aSLionel Sambuc // Visit captures.
2615f4a2713aSLionel Sambuc const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
2616f4a2713aSLionel Sambuc for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2617f4a2713aSLionel Sambuc CEnd = E->explicit_capture_end();
2618f4a2713aSLionel Sambuc C != CEnd; ++C) {
2619f4a2713aSLionel Sambuc // FIXME: Lambda init-captures.
2620f4a2713aSLionel Sambuc if (!C->capturesVariable())
2621f4a2713aSLionel Sambuc continue;
2622f4a2713aSLionel Sambuc
2623f4a2713aSLionel Sambuc if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2624f4a2713aSLionel Sambuc C->getLocation(),
2625f4a2713aSLionel Sambuc TU)))
2626f4a2713aSLionel Sambuc return true;
2627f4a2713aSLionel Sambuc }
2628f4a2713aSLionel Sambuc
2629f4a2713aSLionel Sambuc // Visit parameters and return type, if present.
2630f4a2713aSLionel Sambuc if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2631f4a2713aSLionel Sambuc TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2632f4a2713aSLionel Sambuc if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2633f4a2713aSLionel Sambuc // Visit the whole type.
2634f4a2713aSLionel Sambuc if (Visit(TL))
2635f4a2713aSLionel Sambuc return true;
2636f4a2713aSLionel Sambuc } else if (FunctionProtoTypeLoc Proto =
2637f4a2713aSLionel Sambuc TL.getAs<FunctionProtoTypeLoc>()) {
2638f4a2713aSLionel Sambuc if (E->hasExplicitParameters()) {
2639f4a2713aSLionel Sambuc // Visit parameters.
2640*0a6a1f1dSLionel Sambuc for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2641*0a6a1f1dSLionel Sambuc if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
2642f4a2713aSLionel Sambuc return true;
2643f4a2713aSLionel Sambuc } else {
2644f4a2713aSLionel Sambuc // Visit result type.
2645*0a6a1f1dSLionel Sambuc if (Visit(Proto.getReturnLoc()))
2646f4a2713aSLionel Sambuc return true;
2647f4a2713aSLionel Sambuc }
2648f4a2713aSLionel Sambuc }
2649f4a2713aSLionel Sambuc }
2650f4a2713aSLionel Sambuc break;
2651f4a2713aSLionel Sambuc }
2652f4a2713aSLionel Sambuc
2653f4a2713aSLionel Sambuc case VisitorJob::PostChildrenVisitKind:
2654f4a2713aSLionel Sambuc if (PostChildrenVisitor(Parent, ClientData))
2655f4a2713aSLionel Sambuc return true;
2656f4a2713aSLionel Sambuc break;
2657f4a2713aSLionel Sambuc }
2658f4a2713aSLionel Sambuc }
2659f4a2713aSLionel Sambuc return false;
2660f4a2713aSLionel Sambuc }
2661f4a2713aSLionel Sambuc
Visit(const Stmt * S)2662f4a2713aSLionel Sambuc bool CursorVisitor::Visit(const Stmt *S) {
2663*0a6a1f1dSLionel Sambuc VisitorWorkList *WL = nullptr;
2664f4a2713aSLionel Sambuc if (!WorkListFreeList.empty()) {
2665f4a2713aSLionel Sambuc WL = WorkListFreeList.back();
2666f4a2713aSLionel Sambuc WL->clear();
2667f4a2713aSLionel Sambuc WorkListFreeList.pop_back();
2668f4a2713aSLionel Sambuc }
2669f4a2713aSLionel Sambuc else {
2670f4a2713aSLionel Sambuc WL = new VisitorWorkList();
2671f4a2713aSLionel Sambuc WorkListCache.push_back(WL);
2672f4a2713aSLionel Sambuc }
2673f4a2713aSLionel Sambuc EnqueueWorkList(*WL, S);
2674f4a2713aSLionel Sambuc bool result = RunVisitorWorkList(*WL);
2675f4a2713aSLionel Sambuc WorkListFreeList.push_back(WL);
2676f4a2713aSLionel Sambuc return result;
2677f4a2713aSLionel Sambuc }
2678f4a2713aSLionel Sambuc
2679f4a2713aSLionel Sambuc namespace {
2680f4a2713aSLionel Sambuc typedef SmallVector<SourceRange, 4> RefNamePieces;
2681*0a6a1f1dSLionel Sambuc RefNamePieces
buildPieces(unsigned NameFlags,bool IsMemberRefExpr,const DeclarationNameInfo & NI,const SourceRange & QLoc,const ASTTemplateArgumentListInfo * TemplateArgs=nullptr)2682*0a6a1f1dSLionel Sambuc buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2683*0a6a1f1dSLionel Sambuc const DeclarationNameInfo &NI, const SourceRange &QLoc,
2684*0a6a1f1dSLionel Sambuc const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
2685f4a2713aSLionel Sambuc const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2686f4a2713aSLionel Sambuc const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2687f4a2713aSLionel Sambuc const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2688f4a2713aSLionel Sambuc
2689f4a2713aSLionel Sambuc const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2690f4a2713aSLionel Sambuc
2691f4a2713aSLionel Sambuc RefNamePieces Pieces;
2692f4a2713aSLionel Sambuc
2693f4a2713aSLionel Sambuc if (WantQualifier && QLoc.isValid())
2694f4a2713aSLionel Sambuc Pieces.push_back(QLoc);
2695f4a2713aSLionel Sambuc
2696f4a2713aSLionel Sambuc if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2697f4a2713aSLionel Sambuc Pieces.push_back(NI.getLoc());
2698f4a2713aSLionel Sambuc
2699f4a2713aSLionel Sambuc if (WantTemplateArgs && TemplateArgs)
2700f4a2713aSLionel Sambuc Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2701f4a2713aSLionel Sambuc TemplateArgs->RAngleLoc));
2702f4a2713aSLionel Sambuc
2703f4a2713aSLionel Sambuc if (Kind == DeclarationName::CXXOperatorName) {
2704f4a2713aSLionel Sambuc Pieces.push_back(SourceLocation::getFromRawEncoding(
2705f4a2713aSLionel Sambuc NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2706f4a2713aSLionel Sambuc Pieces.push_back(SourceLocation::getFromRawEncoding(
2707f4a2713aSLionel Sambuc NI.getInfo().CXXOperatorName.EndOpNameLoc));
2708f4a2713aSLionel Sambuc }
2709f4a2713aSLionel Sambuc
2710f4a2713aSLionel Sambuc if (WantSinglePiece) {
2711f4a2713aSLionel Sambuc SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2712f4a2713aSLionel Sambuc Pieces.clear();
2713f4a2713aSLionel Sambuc Pieces.push_back(R);
2714f4a2713aSLionel Sambuc }
2715f4a2713aSLionel Sambuc
2716f4a2713aSLionel Sambuc return Pieces;
2717f4a2713aSLionel Sambuc }
2718f4a2713aSLionel Sambuc }
2719f4a2713aSLionel Sambuc
2720f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2721f4a2713aSLionel Sambuc // Misc. API hooks.
2722f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2723f4a2713aSLionel Sambuc
fatal_error_handler(void * user_data,const std::string & reason,bool gen_crash_diag)2724f4a2713aSLionel Sambuc static void fatal_error_handler(void *user_data, const std::string& reason,
2725f4a2713aSLionel Sambuc bool gen_crash_diag) {
2726f4a2713aSLionel Sambuc // Write the result out to stderr avoiding errs() because raw_ostreams can
2727f4a2713aSLionel Sambuc // call report_fatal_error.
2728f4a2713aSLionel Sambuc fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2729f4a2713aSLionel Sambuc ::abort();
2730f4a2713aSLionel Sambuc }
2731f4a2713aSLionel Sambuc
2732*0a6a1f1dSLionel Sambuc namespace {
2733*0a6a1f1dSLionel Sambuc struct RegisterFatalErrorHandler {
RegisterFatalErrorHandler__anon527c650d0511::RegisterFatalErrorHandler2734*0a6a1f1dSLionel Sambuc RegisterFatalErrorHandler() {
2735*0a6a1f1dSLionel Sambuc llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2736*0a6a1f1dSLionel Sambuc }
2737*0a6a1f1dSLionel Sambuc };
2738*0a6a1f1dSLionel Sambuc }
2739*0a6a1f1dSLionel Sambuc
2740*0a6a1f1dSLionel Sambuc static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2741*0a6a1f1dSLionel Sambuc
2742f4a2713aSLionel Sambuc extern "C" {
clang_createIndex(int excludeDeclarationsFromPCH,int displayDiagnostics)2743f4a2713aSLionel Sambuc CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2744f4a2713aSLionel Sambuc int displayDiagnostics) {
2745f4a2713aSLionel Sambuc // We use crash recovery to make some of our APIs more reliable, implicitly
2746f4a2713aSLionel Sambuc // enable it.
2747*0a6a1f1dSLionel Sambuc if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2748f4a2713aSLionel Sambuc llvm::CrashRecoveryContext::Enable();
2749f4a2713aSLionel Sambuc
2750*0a6a1f1dSLionel Sambuc // Look through the managed static to trigger construction of the managed
2751*0a6a1f1dSLionel Sambuc // static which registers our fatal error handler. This ensures it is only
2752*0a6a1f1dSLionel Sambuc // registered once.
2753*0a6a1f1dSLionel Sambuc (void)*RegisterFatalErrorHandlerOnce;
2754f4a2713aSLionel Sambuc
2755f4a2713aSLionel Sambuc CIndexer *CIdxr = new CIndexer();
2756f4a2713aSLionel Sambuc if (excludeDeclarationsFromPCH)
2757f4a2713aSLionel Sambuc CIdxr->setOnlyLocalDecls();
2758f4a2713aSLionel Sambuc if (displayDiagnostics)
2759f4a2713aSLionel Sambuc CIdxr->setDisplayDiagnostics();
2760f4a2713aSLionel Sambuc
2761f4a2713aSLionel Sambuc if (getenv("LIBCLANG_BGPRIO_INDEX"))
2762f4a2713aSLionel Sambuc CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2763f4a2713aSLionel Sambuc CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2764f4a2713aSLionel Sambuc if (getenv("LIBCLANG_BGPRIO_EDIT"))
2765f4a2713aSLionel Sambuc CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2766f4a2713aSLionel Sambuc CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2767f4a2713aSLionel Sambuc
2768f4a2713aSLionel Sambuc return CIdxr;
2769f4a2713aSLionel Sambuc }
2770f4a2713aSLionel Sambuc
clang_disposeIndex(CXIndex CIdx)2771f4a2713aSLionel Sambuc void clang_disposeIndex(CXIndex CIdx) {
2772f4a2713aSLionel Sambuc if (CIdx)
2773f4a2713aSLionel Sambuc delete static_cast<CIndexer *>(CIdx);
2774f4a2713aSLionel Sambuc }
2775f4a2713aSLionel Sambuc
clang_CXIndex_setGlobalOptions(CXIndex CIdx,unsigned options)2776f4a2713aSLionel Sambuc void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2777f4a2713aSLionel Sambuc if (CIdx)
2778f4a2713aSLionel Sambuc static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2779f4a2713aSLionel Sambuc }
2780f4a2713aSLionel Sambuc
clang_CXIndex_getGlobalOptions(CXIndex CIdx)2781f4a2713aSLionel Sambuc unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2782f4a2713aSLionel Sambuc if (CIdx)
2783f4a2713aSLionel Sambuc return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2784f4a2713aSLionel Sambuc return 0;
2785f4a2713aSLionel Sambuc }
2786f4a2713aSLionel Sambuc
clang_toggleCrashRecovery(unsigned isEnabled)2787f4a2713aSLionel Sambuc void clang_toggleCrashRecovery(unsigned isEnabled) {
2788f4a2713aSLionel Sambuc if (isEnabled)
2789f4a2713aSLionel Sambuc llvm::CrashRecoveryContext::Enable();
2790f4a2713aSLionel Sambuc else
2791f4a2713aSLionel Sambuc llvm::CrashRecoveryContext::Disable();
2792f4a2713aSLionel Sambuc }
2793f4a2713aSLionel Sambuc
clang_createTranslationUnit(CXIndex CIdx,const char * ast_filename)2794f4a2713aSLionel Sambuc CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2795f4a2713aSLionel Sambuc const char *ast_filename) {
2796*0a6a1f1dSLionel Sambuc CXTranslationUnit TU;
2797*0a6a1f1dSLionel Sambuc enum CXErrorCode Result =
2798*0a6a1f1dSLionel Sambuc clang_createTranslationUnit2(CIdx, ast_filename, &TU);
2799*0a6a1f1dSLionel Sambuc (void)Result;
2800*0a6a1f1dSLionel Sambuc assert((TU && Result == CXError_Success) ||
2801*0a6a1f1dSLionel Sambuc (!TU && Result != CXError_Success));
2802*0a6a1f1dSLionel Sambuc return TU;
2803*0a6a1f1dSLionel Sambuc }
2804*0a6a1f1dSLionel Sambuc
clang_createTranslationUnit2(CXIndex CIdx,const char * ast_filename,CXTranslationUnit * out_TU)2805*0a6a1f1dSLionel Sambuc enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2806*0a6a1f1dSLionel Sambuc const char *ast_filename,
2807*0a6a1f1dSLionel Sambuc CXTranslationUnit *out_TU) {
2808*0a6a1f1dSLionel Sambuc if (out_TU)
2809*0a6a1f1dSLionel Sambuc *out_TU = nullptr;
2810*0a6a1f1dSLionel Sambuc
2811*0a6a1f1dSLionel Sambuc if (!CIdx || !ast_filename || !out_TU)
2812*0a6a1f1dSLionel Sambuc return CXError_InvalidArguments;
2813f4a2713aSLionel Sambuc
2814f4a2713aSLionel Sambuc LOG_FUNC_SECTION {
2815f4a2713aSLionel Sambuc *Log << ast_filename;
2816f4a2713aSLionel Sambuc }
2817f4a2713aSLionel Sambuc
2818f4a2713aSLionel Sambuc CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2819f4a2713aSLionel Sambuc FileSystemOptions FileSystemOpts;
2820f4a2713aSLionel Sambuc
2821*0a6a1f1dSLionel Sambuc IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2822*0a6a1f1dSLionel Sambuc CompilerInstance::createDiagnostics(new DiagnosticOptions());
2823*0a6a1f1dSLionel Sambuc std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2824*0a6a1f1dSLionel Sambuc ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2825f4a2713aSLionel Sambuc /*CaptureDiagnostics=*/true,
2826f4a2713aSLionel Sambuc /*AllowPCHWithCompilerErrors=*/true,
2827f4a2713aSLionel Sambuc /*UserFilesAreVolatile=*/true);
2828*0a6a1f1dSLionel Sambuc *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
2829*0a6a1f1dSLionel Sambuc return *out_TU ? CXError_Success : CXError_Failure;
2830f4a2713aSLionel Sambuc }
2831f4a2713aSLionel Sambuc
clang_defaultEditingTranslationUnitOptions()2832f4a2713aSLionel Sambuc unsigned clang_defaultEditingTranslationUnitOptions() {
2833f4a2713aSLionel Sambuc return CXTranslationUnit_PrecompiledPreamble |
2834f4a2713aSLionel Sambuc CXTranslationUnit_CacheCompletionResults;
2835f4a2713aSLionel Sambuc }
2836f4a2713aSLionel Sambuc
2837f4a2713aSLionel Sambuc CXTranslationUnit
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)2838f4a2713aSLionel Sambuc clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2839f4a2713aSLionel Sambuc const char *source_filename,
2840f4a2713aSLionel Sambuc int num_command_line_args,
2841f4a2713aSLionel Sambuc const char * const *command_line_args,
2842f4a2713aSLionel Sambuc unsigned num_unsaved_files,
2843f4a2713aSLionel Sambuc struct CXUnsavedFile *unsaved_files) {
2844f4a2713aSLionel Sambuc unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2845f4a2713aSLionel Sambuc return clang_parseTranslationUnit(CIdx, source_filename,
2846f4a2713aSLionel Sambuc command_line_args, num_command_line_args,
2847f4a2713aSLionel Sambuc unsaved_files, num_unsaved_files,
2848f4a2713aSLionel Sambuc Options);
2849f4a2713aSLionel Sambuc }
2850f4a2713aSLionel Sambuc
2851f4a2713aSLionel Sambuc struct ParseTranslationUnitInfo {
2852f4a2713aSLionel Sambuc CXIndex CIdx;
2853f4a2713aSLionel Sambuc const char *source_filename;
2854f4a2713aSLionel Sambuc const char *const *command_line_args;
2855f4a2713aSLionel Sambuc int num_command_line_args;
2856*0a6a1f1dSLionel Sambuc ArrayRef<CXUnsavedFile> unsaved_files;
2857f4a2713aSLionel Sambuc unsigned options;
2858*0a6a1f1dSLionel Sambuc CXTranslationUnit *out_TU;
2859*0a6a1f1dSLionel Sambuc CXErrorCode &result;
2860f4a2713aSLionel Sambuc };
clang_parseTranslationUnit_Impl(void * UserData)2861f4a2713aSLionel Sambuc static void clang_parseTranslationUnit_Impl(void *UserData) {
2862*0a6a1f1dSLionel Sambuc const ParseTranslationUnitInfo *PTUI =
2863f4a2713aSLionel Sambuc static_cast<ParseTranslationUnitInfo *>(UserData);
2864f4a2713aSLionel Sambuc CXIndex CIdx = PTUI->CIdx;
2865f4a2713aSLionel Sambuc const char *source_filename = PTUI->source_filename;
2866f4a2713aSLionel Sambuc const char * const *command_line_args = PTUI->command_line_args;
2867f4a2713aSLionel Sambuc int num_command_line_args = PTUI->num_command_line_args;
2868f4a2713aSLionel Sambuc unsigned options = PTUI->options;
2869*0a6a1f1dSLionel Sambuc CXTranslationUnit *out_TU = PTUI->out_TU;
2870f4a2713aSLionel Sambuc
2871*0a6a1f1dSLionel Sambuc // Set up the initial return values.
2872*0a6a1f1dSLionel Sambuc if (out_TU)
2873*0a6a1f1dSLionel Sambuc *out_TU = nullptr;
2874*0a6a1f1dSLionel Sambuc
2875*0a6a1f1dSLionel Sambuc // Check arguments.
2876*0a6a1f1dSLionel Sambuc if (!CIdx || !out_TU) {
2877*0a6a1f1dSLionel Sambuc PTUI->result = CXError_InvalidArguments;
2878f4a2713aSLionel Sambuc return;
2879*0a6a1f1dSLionel Sambuc }
2880f4a2713aSLionel Sambuc
2881f4a2713aSLionel Sambuc CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2882f4a2713aSLionel Sambuc
2883f4a2713aSLionel Sambuc if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2884f4a2713aSLionel Sambuc setThreadBackgroundPriority();
2885f4a2713aSLionel Sambuc
2886f4a2713aSLionel Sambuc bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2887f4a2713aSLionel Sambuc // FIXME: Add a flag for modules.
2888f4a2713aSLionel Sambuc TranslationUnitKind TUKind
2889f4a2713aSLionel Sambuc = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2890*0a6a1f1dSLionel Sambuc bool CacheCodeCompletionResults
2891f4a2713aSLionel Sambuc = options & CXTranslationUnit_CacheCompletionResults;
2892f4a2713aSLionel Sambuc bool IncludeBriefCommentsInCodeCompletion
2893f4a2713aSLionel Sambuc = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2894f4a2713aSLionel Sambuc bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2895f4a2713aSLionel Sambuc bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2896f4a2713aSLionel Sambuc
2897f4a2713aSLionel Sambuc // Configure the diagnostics.
2898f4a2713aSLionel Sambuc IntrusiveRefCntPtr<DiagnosticsEngine>
2899f4a2713aSLionel Sambuc Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
2900f4a2713aSLionel Sambuc
2901f4a2713aSLionel Sambuc // Recover resources if we crash before exiting this function.
2902f4a2713aSLionel Sambuc llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2903f4a2713aSLionel Sambuc llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2904*0a6a1f1dSLionel Sambuc DiagCleanup(Diags.get());
2905f4a2713aSLionel Sambuc
2906*0a6a1f1dSLionel Sambuc std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2907*0a6a1f1dSLionel Sambuc new std::vector<ASTUnit::RemappedFile>());
2908f4a2713aSLionel Sambuc
2909f4a2713aSLionel Sambuc // Recover resources if we crash before exiting this function.
2910f4a2713aSLionel Sambuc llvm::CrashRecoveryContextCleanupRegistrar<
2911f4a2713aSLionel Sambuc std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2912f4a2713aSLionel Sambuc
2913*0a6a1f1dSLionel Sambuc for (auto &UF : PTUI->unsaved_files) {
2914*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::MemoryBuffer> MB =
2915*0a6a1f1dSLionel Sambuc llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2916*0a6a1f1dSLionel Sambuc RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
2917f4a2713aSLionel Sambuc }
2918f4a2713aSLionel Sambuc
2919*0a6a1f1dSLionel Sambuc std::unique_ptr<std::vector<const char *>> Args(
2920*0a6a1f1dSLionel Sambuc new std::vector<const char *>());
2921f4a2713aSLionel Sambuc
2922f4a2713aSLionel Sambuc // Recover resources if we crash before exiting this method.
2923f4a2713aSLionel Sambuc llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2924f4a2713aSLionel Sambuc ArgsCleanup(Args.get());
2925f4a2713aSLionel Sambuc
2926f4a2713aSLionel Sambuc // Since the Clang C library is primarily used by batch tools dealing with
2927f4a2713aSLionel Sambuc // (often very broken) source code, where spell-checking can have a
2928f4a2713aSLionel Sambuc // significant negative impact on performance (particularly when
2929f4a2713aSLionel Sambuc // precompiled headers are involved), we disable it by default.
2930f4a2713aSLionel Sambuc // Only do this if we haven't found a spell-checking-related argument.
2931f4a2713aSLionel Sambuc bool FoundSpellCheckingArgument = false;
2932f4a2713aSLionel Sambuc for (int I = 0; I != num_command_line_args; ++I) {
2933f4a2713aSLionel Sambuc if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2934f4a2713aSLionel Sambuc strcmp(command_line_args[I], "-fspell-checking") == 0) {
2935f4a2713aSLionel Sambuc FoundSpellCheckingArgument = true;
2936f4a2713aSLionel Sambuc break;
2937f4a2713aSLionel Sambuc }
2938f4a2713aSLionel Sambuc }
2939f4a2713aSLionel Sambuc if (!FoundSpellCheckingArgument)
2940f4a2713aSLionel Sambuc Args->push_back("-fno-spell-checking");
2941f4a2713aSLionel Sambuc
2942f4a2713aSLionel Sambuc Args->insert(Args->end(), command_line_args,
2943f4a2713aSLionel Sambuc command_line_args + num_command_line_args);
2944f4a2713aSLionel Sambuc
2945f4a2713aSLionel Sambuc // The 'source_filename' argument is optional. If the caller does not
2946f4a2713aSLionel Sambuc // specify it then it is assumed that the source file is specified
2947f4a2713aSLionel Sambuc // in the actual argument list.
2948f4a2713aSLionel Sambuc // Put the source file after command_line_args otherwise if '-x' flag is
2949f4a2713aSLionel Sambuc // present it will be unused.
2950f4a2713aSLionel Sambuc if (source_filename)
2951f4a2713aSLionel Sambuc Args->push_back(source_filename);
2952f4a2713aSLionel Sambuc
2953f4a2713aSLionel Sambuc // Do we need the detailed preprocessing record?
2954f4a2713aSLionel Sambuc if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2955f4a2713aSLionel Sambuc Args->push_back("-Xclang");
2956f4a2713aSLionel Sambuc Args->push_back("-detailed-preprocessing-record");
2957f4a2713aSLionel Sambuc }
2958f4a2713aSLionel Sambuc
2959f4a2713aSLionel Sambuc unsigned NumErrors = Diags->getClient()->getNumErrors();
2960*0a6a1f1dSLionel Sambuc std::unique_ptr<ASTUnit> ErrUnit;
2961*0a6a1f1dSLionel Sambuc std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
2962*0a6a1f1dSLionel Sambuc Args->data(), Args->data() + Args->size(), Diags,
2963*0a6a1f1dSLionel Sambuc CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2964*0a6a1f1dSLionel Sambuc /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2965*0a6a1f1dSLionel Sambuc /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2966*0a6a1f1dSLionel Sambuc CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2967*0a6a1f1dSLionel Sambuc /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2968*0a6a1f1dSLionel Sambuc /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
2969f4a2713aSLionel Sambuc
2970f4a2713aSLionel Sambuc if (NumErrors != Diags->getClient()->getNumErrors()) {
2971f4a2713aSLionel Sambuc // Make sure to check that 'Unit' is non-NULL.
2972f4a2713aSLionel Sambuc if (CXXIdx->getDisplayDiagnostics())
2973f4a2713aSLionel Sambuc printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2974f4a2713aSLionel Sambuc }
2975f4a2713aSLionel Sambuc
2976*0a6a1f1dSLionel Sambuc if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2977*0a6a1f1dSLionel Sambuc PTUI->result = CXError_ASTReadError;
2978*0a6a1f1dSLionel Sambuc } else {
2979*0a6a1f1dSLionel Sambuc *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
2980*0a6a1f1dSLionel Sambuc PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2981f4a2713aSLionel Sambuc }
2982*0a6a1f1dSLionel Sambuc }
2983*0a6a1f1dSLionel Sambuc
2984*0a6a1f1dSLionel Sambuc 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)2985*0a6a1f1dSLionel Sambuc clang_parseTranslationUnit(CXIndex CIdx,
2986f4a2713aSLionel Sambuc const char *source_filename,
2987f4a2713aSLionel Sambuc const char *const *command_line_args,
2988f4a2713aSLionel Sambuc int num_command_line_args,
2989f4a2713aSLionel Sambuc struct CXUnsavedFile *unsaved_files,
2990f4a2713aSLionel Sambuc unsigned num_unsaved_files,
2991f4a2713aSLionel Sambuc unsigned options) {
2992*0a6a1f1dSLionel Sambuc CXTranslationUnit TU;
2993*0a6a1f1dSLionel Sambuc enum CXErrorCode Result = clang_parseTranslationUnit2(
2994*0a6a1f1dSLionel Sambuc CIdx, source_filename, command_line_args, num_command_line_args,
2995*0a6a1f1dSLionel Sambuc unsaved_files, num_unsaved_files, options, &TU);
2996*0a6a1f1dSLionel Sambuc (void)Result;
2997*0a6a1f1dSLionel Sambuc assert((TU && Result == CXError_Success) ||
2998*0a6a1f1dSLionel Sambuc (!TU && Result != CXError_Success));
2999*0a6a1f1dSLionel Sambuc return TU;
3000*0a6a1f1dSLionel Sambuc }
3001*0a6a1f1dSLionel Sambuc
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)3002*0a6a1f1dSLionel Sambuc enum CXErrorCode clang_parseTranslationUnit2(
3003*0a6a1f1dSLionel Sambuc CXIndex CIdx,
3004*0a6a1f1dSLionel Sambuc const char *source_filename,
3005*0a6a1f1dSLionel Sambuc const char *const *command_line_args,
3006*0a6a1f1dSLionel Sambuc int num_command_line_args,
3007*0a6a1f1dSLionel Sambuc struct CXUnsavedFile *unsaved_files,
3008*0a6a1f1dSLionel Sambuc unsigned num_unsaved_files,
3009*0a6a1f1dSLionel Sambuc unsigned options,
3010*0a6a1f1dSLionel Sambuc CXTranslationUnit *out_TU) {
3011f4a2713aSLionel Sambuc LOG_FUNC_SECTION {
3012f4a2713aSLionel Sambuc *Log << source_filename << ": ";
3013f4a2713aSLionel Sambuc for (int i = 0; i != num_command_line_args; ++i)
3014f4a2713aSLionel Sambuc *Log << command_line_args[i] << " ";
3015f4a2713aSLionel Sambuc }
3016f4a2713aSLionel Sambuc
3017*0a6a1f1dSLionel Sambuc if (num_unsaved_files && !unsaved_files)
3018*0a6a1f1dSLionel Sambuc return CXError_InvalidArguments;
3019*0a6a1f1dSLionel Sambuc
3020*0a6a1f1dSLionel Sambuc CXErrorCode result = CXError_Failure;
3021*0a6a1f1dSLionel Sambuc ParseTranslationUnitInfo PTUI = {
3022*0a6a1f1dSLionel Sambuc CIdx,
3023*0a6a1f1dSLionel Sambuc source_filename,
3024*0a6a1f1dSLionel Sambuc command_line_args,
3025*0a6a1f1dSLionel Sambuc num_command_line_args,
3026*0a6a1f1dSLionel Sambuc llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3027*0a6a1f1dSLionel Sambuc options,
3028*0a6a1f1dSLionel Sambuc out_TU,
3029*0a6a1f1dSLionel Sambuc result};
3030f4a2713aSLionel Sambuc llvm::CrashRecoveryContext CRC;
3031f4a2713aSLionel Sambuc
3032f4a2713aSLionel Sambuc if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3033f4a2713aSLionel Sambuc fprintf(stderr, "libclang: crash detected during parsing: {\n");
3034f4a2713aSLionel Sambuc fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3035f4a2713aSLionel Sambuc fprintf(stderr, " 'command_line_args' : [");
3036f4a2713aSLionel Sambuc for (int i = 0; i != num_command_line_args; ++i) {
3037f4a2713aSLionel Sambuc if (i)
3038f4a2713aSLionel Sambuc fprintf(stderr, ", ");
3039f4a2713aSLionel Sambuc fprintf(stderr, "'%s'", command_line_args[i]);
3040f4a2713aSLionel Sambuc }
3041f4a2713aSLionel Sambuc fprintf(stderr, "],\n");
3042f4a2713aSLionel Sambuc fprintf(stderr, " 'unsaved_files' : [");
3043f4a2713aSLionel Sambuc for (unsigned i = 0; i != num_unsaved_files; ++i) {
3044f4a2713aSLionel Sambuc if (i)
3045f4a2713aSLionel Sambuc fprintf(stderr, ", ");
3046f4a2713aSLionel Sambuc fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3047f4a2713aSLionel Sambuc unsaved_files[i].Length);
3048f4a2713aSLionel Sambuc }
3049f4a2713aSLionel Sambuc fprintf(stderr, "],\n");
3050f4a2713aSLionel Sambuc fprintf(stderr, " 'options' : %d,\n", options);
3051f4a2713aSLionel Sambuc fprintf(stderr, "}\n");
3052f4a2713aSLionel Sambuc
3053*0a6a1f1dSLionel Sambuc return CXError_Crashed;
3054f4a2713aSLionel Sambuc } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3055*0a6a1f1dSLionel Sambuc if (CXTranslationUnit *TU = PTUI.out_TU)
3056*0a6a1f1dSLionel Sambuc PrintLibclangResourceUsage(*TU);
3057f4a2713aSLionel Sambuc }
3058f4a2713aSLionel Sambuc
3059*0a6a1f1dSLionel Sambuc return result;
3060f4a2713aSLionel Sambuc }
3061f4a2713aSLionel Sambuc
clang_defaultSaveOptions(CXTranslationUnit TU)3062f4a2713aSLionel Sambuc unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3063f4a2713aSLionel Sambuc return CXSaveTranslationUnit_None;
3064f4a2713aSLionel Sambuc }
3065f4a2713aSLionel Sambuc
3066f4a2713aSLionel Sambuc namespace {
3067f4a2713aSLionel Sambuc
3068f4a2713aSLionel Sambuc struct SaveTranslationUnitInfo {
3069f4a2713aSLionel Sambuc CXTranslationUnit TU;
3070f4a2713aSLionel Sambuc const char *FileName;
3071f4a2713aSLionel Sambuc unsigned options;
3072f4a2713aSLionel Sambuc CXSaveError result;
3073f4a2713aSLionel Sambuc };
3074f4a2713aSLionel Sambuc
3075f4a2713aSLionel Sambuc }
3076f4a2713aSLionel Sambuc
clang_saveTranslationUnit_Impl(void * UserData)3077f4a2713aSLionel Sambuc static void clang_saveTranslationUnit_Impl(void *UserData) {
3078f4a2713aSLionel Sambuc SaveTranslationUnitInfo *STUI =
3079f4a2713aSLionel Sambuc static_cast<SaveTranslationUnitInfo*>(UserData);
3080f4a2713aSLionel Sambuc
3081f4a2713aSLionel Sambuc CIndexer *CXXIdx = STUI->TU->CIdx;
3082f4a2713aSLionel Sambuc if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3083f4a2713aSLionel Sambuc setThreadBackgroundPriority();
3084f4a2713aSLionel Sambuc
3085f4a2713aSLionel Sambuc bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
3086f4a2713aSLionel Sambuc STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3087f4a2713aSLionel Sambuc }
3088f4a2713aSLionel Sambuc
clang_saveTranslationUnit(CXTranslationUnit TU,const char * FileName,unsigned options)3089f4a2713aSLionel Sambuc int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3090f4a2713aSLionel Sambuc unsigned options) {
3091f4a2713aSLionel Sambuc LOG_FUNC_SECTION {
3092f4a2713aSLionel Sambuc *Log << TU << ' ' << FileName;
3093f4a2713aSLionel Sambuc }
3094f4a2713aSLionel Sambuc
3095*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
3096*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
3097f4a2713aSLionel Sambuc return CXSaveError_InvalidTU;
3098*0a6a1f1dSLionel Sambuc }
3099f4a2713aSLionel Sambuc
3100f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3101f4a2713aSLionel Sambuc ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3102f4a2713aSLionel Sambuc if (!CXXUnit->hasSema())
3103f4a2713aSLionel Sambuc return CXSaveError_InvalidTU;
3104f4a2713aSLionel Sambuc
3105f4a2713aSLionel Sambuc SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3106f4a2713aSLionel Sambuc
3107f4a2713aSLionel Sambuc if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3108f4a2713aSLionel Sambuc getenv("LIBCLANG_NOTHREADS")) {
3109f4a2713aSLionel Sambuc clang_saveTranslationUnit_Impl(&STUI);
3110f4a2713aSLionel Sambuc
3111f4a2713aSLionel Sambuc if (getenv("LIBCLANG_RESOURCE_USAGE"))
3112f4a2713aSLionel Sambuc PrintLibclangResourceUsage(TU);
3113f4a2713aSLionel Sambuc
3114f4a2713aSLionel Sambuc return STUI.result;
3115f4a2713aSLionel Sambuc }
3116f4a2713aSLionel Sambuc
3117f4a2713aSLionel Sambuc // We have an AST that has invalid nodes due to compiler errors.
3118f4a2713aSLionel Sambuc // Use a crash recovery thread for protection.
3119f4a2713aSLionel Sambuc
3120f4a2713aSLionel Sambuc llvm::CrashRecoveryContext CRC;
3121f4a2713aSLionel Sambuc
3122f4a2713aSLionel Sambuc if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3123f4a2713aSLionel Sambuc fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3124f4a2713aSLionel Sambuc fprintf(stderr, " 'filename' : '%s'\n", FileName);
3125f4a2713aSLionel Sambuc fprintf(stderr, " 'options' : %d,\n", options);
3126f4a2713aSLionel Sambuc fprintf(stderr, "}\n");
3127f4a2713aSLionel Sambuc
3128f4a2713aSLionel Sambuc return CXSaveError_Unknown;
3129f4a2713aSLionel Sambuc
3130f4a2713aSLionel Sambuc } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3131f4a2713aSLionel Sambuc PrintLibclangResourceUsage(TU);
3132f4a2713aSLionel Sambuc }
3133f4a2713aSLionel Sambuc
3134f4a2713aSLionel Sambuc return STUI.result;
3135f4a2713aSLionel Sambuc }
3136f4a2713aSLionel Sambuc
clang_disposeTranslationUnit(CXTranslationUnit CTUnit)3137f4a2713aSLionel Sambuc void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3138f4a2713aSLionel Sambuc if (CTUnit) {
3139f4a2713aSLionel Sambuc // If the translation unit has been marked as unsafe to free, just discard
3140f4a2713aSLionel Sambuc // it.
3141*0a6a1f1dSLionel Sambuc ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3142*0a6a1f1dSLionel Sambuc if (Unit && Unit->isUnsafeToFree())
3143f4a2713aSLionel Sambuc return;
3144f4a2713aSLionel Sambuc
3145f4a2713aSLionel Sambuc delete cxtu::getASTUnit(CTUnit);
3146f4a2713aSLionel Sambuc delete CTUnit->StringPool;
3147f4a2713aSLionel Sambuc delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3148f4a2713aSLionel Sambuc disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
3149f4a2713aSLionel Sambuc delete CTUnit->CommentToXML;
3150f4a2713aSLionel Sambuc delete CTUnit;
3151f4a2713aSLionel Sambuc }
3152f4a2713aSLionel Sambuc }
3153f4a2713aSLionel Sambuc
clang_defaultReparseOptions(CXTranslationUnit TU)3154f4a2713aSLionel Sambuc unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3155f4a2713aSLionel Sambuc return CXReparse_None;
3156f4a2713aSLionel Sambuc }
3157f4a2713aSLionel Sambuc
3158f4a2713aSLionel Sambuc struct ReparseTranslationUnitInfo {
3159f4a2713aSLionel Sambuc CXTranslationUnit TU;
3160*0a6a1f1dSLionel Sambuc ArrayRef<CXUnsavedFile> unsaved_files;
3161f4a2713aSLionel Sambuc unsigned options;
3162*0a6a1f1dSLionel Sambuc CXErrorCode &result;
3163f4a2713aSLionel Sambuc };
3164f4a2713aSLionel Sambuc
clang_reparseTranslationUnit_Impl(void * UserData)3165f4a2713aSLionel Sambuc static void clang_reparseTranslationUnit_Impl(void *UserData) {
3166*0a6a1f1dSLionel Sambuc const ReparseTranslationUnitInfo *RTUI =
3167f4a2713aSLionel Sambuc static_cast<ReparseTranslationUnitInfo *>(UserData);
3168f4a2713aSLionel Sambuc CXTranslationUnit TU = RTUI->TU;
3169*0a6a1f1dSLionel Sambuc unsigned options = RTUI->options;
3170*0a6a1f1dSLionel Sambuc (void) options;
3171*0a6a1f1dSLionel Sambuc
3172*0a6a1f1dSLionel Sambuc // Check arguments.
3173*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
3174*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
3175*0a6a1f1dSLionel Sambuc RTUI->result = CXError_InvalidArguments;
3176f4a2713aSLionel Sambuc return;
3177*0a6a1f1dSLionel Sambuc }
3178f4a2713aSLionel Sambuc
3179f4a2713aSLionel Sambuc // Reset the associated diagnostics.
3180f4a2713aSLionel Sambuc delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3181*0a6a1f1dSLionel Sambuc TU->Diagnostics = nullptr;
3182f4a2713aSLionel Sambuc
3183f4a2713aSLionel Sambuc CIndexer *CXXIdx = TU->CIdx;
3184f4a2713aSLionel Sambuc if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3185f4a2713aSLionel Sambuc setThreadBackgroundPriority();
3186f4a2713aSLionel Sambuc
3187f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3188f4a2713aSLionel Sambuc ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3189f4a2713aSLionel Sambuc
3190*0a6a1f1dSLionel Sambuc std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3191*0a6a1f1dSLionel Sambuc new std::vector<ASTUnit::RemappedFile>());
3192f4a2713aSLionel Sambuc
3193f4a2713aSLionel Sambuc // Recover resources if we crash before exiting this function.
3194f4a2713aSLionel Sambuc llvm::CrashRecoveryContextCleanupRegistrar<
3195f4a2713aSLionel Sambuc std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3196f4a2713aSLionel Sambuc
3197*0a6a1f1dSLionel Sambuc for (auto &UF : RTUI->unsaved_files) {
3198*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::MemoryBuffer> MB =
3199*0a6a1f1dSLionel Sambuc llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3200*0a6a1f1dSLionel Sambuc RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
3201f4a2713aSLionel Sambuc }
3202f4a2713aSLionel Sambuc
3203*0a6a1f1dSLionel Sambuc if (!CXXUnit->Reparse(*RemappedFiles.get()))
3204*0a6a1f1dSLionel Sambuc RTUI->result = CXError_Success;
3205*0a6a1f1dSLionel Sambuc else if (isASTReadError(CXXUnit))
3206*0a6a1f1dSLionel Sambuc RTUI->result = CXError_ASTReadError;
3207f4a2713aSLionel Sambuc }
3208f4a2713aSLionel Sambuc
clang_reparseTranslationUnit(CXTranslationUnit TU,unsigned num_unsaved_files,struct CXUnsavedFile * unsaved_files,unsigned options)3209f4a2713aSLionel Sambuc int clang_reparseTranslationUnit(CXTranslationUnit TU,
3210f4a2713aSLionel Sambuc unsigned num_unsaved_files,
3211f4a2713aSLionel Sambuc struct CXUnsavedFile *unsaved_files,
3212f4a2713aSLionel Sambuc unsigned options) {
3213f4a2713aSLionel Sambuc LOG_FUNC_SECTION {
3214f4a2713aSLionel Sambuc *Log << TU;
3215f4a2713aSLionel Sambuc }
3216f4a2713aSLionel Sambuc
3217*0a6a1f1dSLionel Sambuc if (num_unsaved_files && !unsaved_files)
3218*0a6a1f1dSLionel Sambuc return CXError_InvalidArguments;
3219*0a6a1f1dSLionel Sambuc
3220*0a6a1f1dSLionel Sambuc CXErrorCode result = CXError_Failure;
3221*0a6a1f1dSLionel Sambuc ReparseTranslationUnitInfo RTUI = {
3222*0a6a1f1dSLionel Sambuc TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
3223*0a6a1f1dSLionel Sambuc result};
3224f4a2713aSLionel Sambuc
3225f4a2713aSLionel Sambuc if (getenv("LIBCLANG_NOTHREADS")) {
3226f4a2713aSLionel Sambuc clang_reparseTranslationUnit_Impl(&RTUI);
3227*0a6a1f1dSLionel Sambuc return result;
3228f4a2713aSLionel Sambuc }
3229f4a2713aSLionel Sambuc
3230f4a2713aSLionel Sambuc llvm::CrashRecoveryContext CRC;
3231f4a2713aSLionel Sambuc
3232f4a2713aSLionel Sambuc if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3233f4a2713aSLionel Sambuc fprintf(stderr, "libclang: crash detected during reparsing\n");
3234f4a2713aSLionel Sambuc cxtu::getASTUnit(TU)->setUnsafeToFree(true);
3235*0a6a1f1dSLionel Sambuc return CXError_Crashed;
3236f4a2713aSLionel Sambuc } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3237f4a2713aSLionel Sambuc PrintLibclangResourceUsage(TU);
3238f4a2713aSLionel Sambuc
3239*0a6a1f1dSLionel Sambuc return result;
3240f4a2713aSLionel Sambuc }
3241f4a2713aSLionel Sambuc
3242f4a2713aSLionel Sambuc
clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit)3243f4a2713aSLionel Sambuc CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
3244*0a6a1f1dSLionel Sambuc if (isNotUsableTU(CTUnit)) {
3245*0a6a1f1dSLionel Sambuc LOG_BAD_TU(CTUnit);
3246f4a2713aSLionel Sambuc return cxstring::createEmpty();
3247*0a6a1f1dSLionel Sambuc }
3248f4a2713aSLionel Sambuc
3249f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
3250f4a2713aSLionel Sambuc return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
3251f4a2713aSLionel Sambuc }
3252f4a2713aSLionel Sambuc
clang_getTranslationUnitCursor(CXTranslationUnit TU)3253f4a2713aSLionel Sambuc CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
3254*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
3255*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
3256f4a2713aSLionel Sambuc return clang_getNullCursor();
3257*0a6a1f1dSLionel Sambuc }
3258f4a2713aSLionel Sambuc
3259f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3260f4a2713aSLionel Sambuc return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3261f4a2713aSLionel Sambuc }
3262f4a2713aSLionel Sambuc
3263f4a2713aSLionel Sambuc } // end: extern "C"
3264f4a2713aSLionel Sambuc
3265f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3266f4a2713aSLionel Sambuc // CXFile Operations.
3267f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3268f4a2713aSLionel Sambuc
3269f4a2713aSLionel Sambuc extern "C" {
clang_getFileName(CXFile SFile)3270f4a2713aSLionel Sambuc CXString clang_getFileName(CXFile SFile) {
3271f4a2713aSLionel Sambuc if (!SFile)
3272f4a2713aSLionel Sambuc return cxstring::createNull();
3273f4a2713aSLionel Sambuc
3274f4a2713aSLionel Sambuc FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3275f4a2713aSLionel Sambuc return cxstring::createRef(FEnt->getName());
3276f4a2713aSLionel Sambuc }
3277f4a2713aSLionel Sambuc
clang_getFileTime(CXFile SFile)3278f4a2713aSLionel Sambuc time_t clang_getFileTime(CXFile SFile) {
3279f4a2713aSLionel Sambuc if (!SFile)
3280f4a2713aSLionel Sambuc return 0;
3281f4a2713aSLionel Sambuc
3282f4a2713aSLionel Sambuc FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3283f4a2713aSLionel Sambuc return FEnt->getModificationTime();
3284f4a2713aSLionel Sambuc }
3285f4a2713aSLionel Sambuc
clang_getFile(CXTranslationUnit TU,const char * file_name)3286f4a2713aSLionel Sambuc CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3287*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
3288*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
3289*0a6a1f1dSLionel Sambuc return nullptr;
3290*0a6a1f1dSLionel Sambuc }
3291f4a2713aSLionel Sambuc
3292f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3293f4a2713aSLionel Sambuc
3294f4a2713aSLionel Sambuc FileManager &FMgr = CXXUnit->getFileManager();
3295f4a2713aSLionel Sambuc return const_cast<FileEntry *>(FMgr.getFile(file_name));
3296f4a2713aSLionel Sambuc }
3297f4a2713aSLionel Sambuc
clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,CXFile file)3298*0a6a1f1dSLionel Sambuc unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3299*0a6a1f1dSLionel Sambuc CXFile file) {
3300*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
3301*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
3302*0a6a1f1dSLionel Sambuc return 0;
3303*0a6a1f1dSLionel Sambuc }
3304*0a6a1f1dSLionel Sambuc
3305*0a6a1f1dSLionel Sambuc if (!file)
3306f4a2713aSLionel Sambuc return 0;
3307f4a2713aSLionel Sambuc
3308f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3309f4a2713aSLionel Sambuc FileEntry *FEnt = static_cast<FileEntry *>(file);
3310f4a2713aSLionel Sambuc return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3311f4a2713aSLionel Sambuc .isFileMultipleIncludeGuarded(FEnt);
3312f4a2713aSLionel Sambuc }
3313f4a2713aSLionel Sambuc
clang_getFileUniqueID(CXFile file,CXFileUniqueID * outID)3314f4a2713aSLionel Sambuc int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3315f4a2713aSLionel Sambuc if (!file || !outID)
3316f4a2713aSLionel Sambuc return 1;
3317f4a2713aSLionel Sambuc
3318f4a2713aSLionel Sambuc FileEntry *FEnt = static_cast<FileEntry *>(file);
3319f4a2713aSLionel Sambuc const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3320f4a2713aSLionel Sambuc outID->data[0] = ID.getDevice();
3321f4a2713aSLionel Sambuc outID->data[1] = ID.getFile();
3322f4a2713aSLionel Sambuc outID->data[2] = FEnt->getModificationTime();
3323f4a2713aSLionel Sambuc return 0;
3324f4a2713aSLionel Sambuc }
3325f4a2713aSLionel Sambuc
clang_File_isEqual(CXFile file1,CXFile file2)3326*0a6a1f1dSLionel Sambuc int clang_File_isEqual(CXFile file1, CXFile file2) {
3327*0a6a1f1dSLionel Sambuc if (file1 == file2)
3328*0a6a1f1dSLionel Sambuc return true;
3329*0a6a1f1dSLionel Sambuc
3330*0a6a1f1dSLionel Sambuc if (!file1 || !file2)
3331*0a6a1f1dSLionel Sambuc return false;
3332*0a6a1f1dSLionel Sambuc
3333*0a6a1f1dSLionel Sambuc FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3334*0a6a1f1dSLionel Sambuc FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3335*0a6a1f1dSLionel Sambuc return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3336*0a6a1f1dSLionel Sambuc }
3337*0a6a1f1dSLionel Sambuc
3338f4a2713aSLionel Sambuc } // end: extern "C"
3339f4a2713aSLionel Sambuc
3340f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3341f4a2713aSLionel Sambuc // CXCursor Operations.
3342f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3343f4a2713aSLionel Sambuc
getDeclFromExpr(const Stmt * E)3344f4a2713aSLionel Sambuc static const Decl *getDeclFromExpr(const Stmt *E) {
3345f4a2713aSLionel Sambuc if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
3346f4a2713aSLionel Sambuc return getDeclFromExpr(CE->getSubExpr());
3347f4a2713aSLionel Sambuc
3348f4a2713aSLionel Sambuc if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
3349f4a2713aSLionel Sambuc return RefExpr->getDecl();
3350f4a2713aSLionel Sambuc if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
3351f4a2713aSLionel Sambuc return ME->getMemberDecl();
3352f4a2713aSLionel Sambuc if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
3353f4a2713aSLionel Sambuc return RE->getDecl();
3354f4a2713aSLionel Sambuc if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
3355f4a2713aSLionel Sambuc if (PRE->isExplicitProperty())
3356f4a2713aSLionel Sambuc return PRE->getExplicitProperty();
3357f4a2713aSLionel Sambuc // It could be messaging both getter and setter as in:
3358f4a2713aSLionel Sambuc // ++myobj.myprop;
3359f4a2713aSLionel Sambuc // in which case prefer to associate the setter since it is less obvious
3360f4a2713aSLionel Sambuc // from inspecting the source that the setter is going to get called.
3361f4a2713aSLionel Sambuc if (PRE->isMessagingSetter())
3362f4a2713aSLionel Sambuc return PRE->getImplicitPropertySetter();
3363f4a2713aSLionel Sambuc return PRE->getImplicitPropertyGetter();
3364f4a2713aSLionel Sambuc }
3365f4a2713aSLionel Sambuc if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
3366f4a2713aSLionel Sambuc return getDeclFromExpr(POE->getSyntacticForm());
3367f4a2713aSLionel Sambuc if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
3368f4a2713aSLionel Sambuc if (Expr *Src = OVE->getSourceExpr())
3369f4a2713aSLionel Sambuc return getDeclFromExpr(Src);
3370f4a2713aSLionel Sambuc
3371f4a2713aSLionel Sambuc if (const CallExpr *CE = dyn_cast<CallExpr>(E))
3372f4a2713aSLionel Sambuc return getDeclFromExpr(CE->getCallee());
3373f4a2713aSLionel Sambuc if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
3374f4a2713aSLionel Sambuc if (!CE->isElidable())
3375f4a2713aSLionel Sambuc return CE->getConstructor();
3376f4a2713aSLionel Sambuc if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
3377f4a2713aSLionel Sambuc return OME->getMethodDecl();
3378f4a2713aSLionel Sambuc
3379f4a2713aSLionel Sambuc if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
3380f4a2713aSLionel Sambuc return PE->getProtocol();
3381f4a2713aSLionel Sambuc if (const SubstNonTypeTemplateParmPackExpr *NTTP
3382f4a2713aSLionel Sambuc = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3383f4a2713aSLionel Sambuc return NTTP->getParameterPack();
3384f4a2713aSLionel Sambuc if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
3385f4a2713aSLionel Sambuc if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3386f4a2713aSLionel Sambuc isa<ParmVarDecl>(SizeOfPack->getPack()))
3387f4a2713aSLionel Sambuc return SizeOfPack->getPack();
3388f4a2713aSLionel Sambuc
3389*0a6a1f1dSLionel Sambuc return nullptr;
3390f4a2713aSLionel Sambuc }
3391f4a2713aSLionel Sambuc
getLocationFromExpr(const Expr * E)3392f4a2713aSLionel Sambuc static SourceLocation getLocationFromExpr(const Expr *E) {
3393f4a2713aSLionel Sambuc if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
3394f4a2713aSLionel Sambuc return getLocationFromExpr(CE->getSubExpr());
3395f4a2713aSLionel Sambuc
3396f4a2713aSLionel Sambuc if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
3397f4a2713aSLionel Sambuc return /*FIXME:*/Msg->getLeftLoc();
3398f4a2713aSLionel Sambuc if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
3399f4a2713aSLionel Sambuc return DRE->getLocation();
3400f4a2713aSLionel Sambuc if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
3401f4a2713aSLionel Sambuc return Member->getMemberLoc();
3402f4a2713aSLionel Sambuc if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
3403f4a2713aSLionel Sambuc return Ivar->getLocation();
3404f4a2713aSLionel Sambuc if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
3405f4a2713aSLionel Sambuc return SizeOfPack->getPackLoc();
3406f4a2713aSLionel Sambuc if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
3407f4a2713aSLionel Sambuc return PropRef->getLocation();
3408f4a2713aSLionel Sambuc
3409f4a2713aSLionel Sambuc return E->getLocStart();
3410f4a2713aSLionel Sambuc }
3411f4a2713aSLionel Sambuc
3412f4a2713aSLionel Sambuc extern "C" {
3413f4a2713aSLionel Sambuc
clang_visitChildren(CXCursor parent,CXCursorVisitor visitor,CXClientData client_data)3414f4a2713aSLionel Sambuc unsigned clang_visitChildren(CXCursor parent,
3415f4a2713aSLionel Sambuc CXCursorVisitor visitor,
3416f4a2713aSLionel Sambuc CXClientData client_data) {
3417f4a2713aSLionel Sambuc CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3418f4a2713aSLionel Sambuc /*VisitPreprocessorLast=*/false);
3419f4a2713aSLionel Sambuc return CursorVis.VisitChildren(parent);
3420f4a2713aSLionel Sambuc }
3421f4a2713aSLionel Sambuc
3422f4a2713aSLionel Sambuc #ifndef __has_feature
3423f4a2713aSLionel Sambuc #define __has_feature(x) 0
3424f4a2713aSLionel Sambuc #endif
3425f4a2713aSLionel Sambuc #if __has_feature(blocks)
3426f4a2713aSLionel Sambuc typedef enum CXChildVisitResult
3427f4a2713aSLionel Sambuc (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3428f4a2713aSLionel Sambuc
visitWithBlock(CXCursor cursor,CXCursor parent,CXClientData client_data)3429f4a2713aSLionel Sambuc static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3430f4a2713aSLionel Sambuc CXClientData client_data) {
3431f4a2713aSLionel Sambuc CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3432f4a2713aSLionel Sambuc return block(cursor, parent);
3433f4a2713aSLionel Sambuc }
3434f4a2713aSLionel Sambuc #else
3435f4a2713aSLionel Sambuc // If we are compiled with a compiler that doesn't have native blocks support,
3436f4a2713aSLionel Sambuc // define and call the block manually, so the
3437f4a2713aSLionel Sambuc typedef struct _CXChildVisitResult
3438f4a2713aSLionel Sambuc {
3439f4a2713aSLionel Sambuc void *isa;
3440f4a2713aSLionel Sambuc int flags;
3441f4a2713aSLionel Sambuc int reserved;
3442f4a2713aSLionel Sambuc enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3443f4a2713aSLionel Sambuc CXCursor);
3444f4a2713aSLionel Sambuc } *CXCursorVisitorBlock;
3445f4a2713aSLionel Sambuc
visitWithBlock(CXCursor cursor,CXCursor parent,CXClientData client_data)3446f4a2713aSLionel Sambuc static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3447f4a2713aSLionel Sambuc CXClientData client_data) {
3448f4a2713aSLionel Sambuc CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3449f4a2713aSLionel Sambuc return block->invoke(block, cursor, parent);
3450f4a2713aSLionel Sambuc }
3451f4a2713aSLionel Sambuc #endif
3452f4a2713aSLionel Sambuc
3453f4a2713aSLionel Sambuc
clang_visitChildrenWithBlock(CXCursor parent,CXCursorVisitorBlock block)3454f4a2713aSLionel Sambuc unsigned clang_visitChildrenWithBlock(CXCursor parent,
3455f4a2713aSLionel Sambuc CXCursorVisitorBlock block) {
3456f4a2713aSLionel Sambuc return clang_visitChildren(parent, visitWithBlock, block);
3457f4a2713aSLionel Sambuc }
3458f4a2713aSLionel Sambuc
getDeclSpelling(const Decl * D)3459f4a2713aSLionel Sambuc static CXString getDeclSpelling(const Decl *D) {
3460f4a2713aSLionel Sambuc if (!D)
3461f4a2713aSLionel Sambuc return cxstring::createEmpty();
3462f4a2713aSLionel Sambuc
3463f4a2713aSLionel Sambuc const NamedDecl *ND = dyn_cast<NamedDecl>(D);
3464f4a2713aSLionel Sambuc if (!ND) {
3465f4a2713aSLionel Sambuc if (const ObjCPropertyImplDecl *PropImpl =
3466f4a2713aSLionel Sambuc dyn_cast<ObjCPropertyImplDecl>(D))
3467f4a2713aSLionel Sambuc if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3468f4a2713aSLionel Sambuc return cxstring::createDup(Property->getIdentifier()->getName());
3469f4a2713aSLionel Sambuc
3470f4a2713aSLionel Sambuc if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
3471f4a2713aSLionel Sambuc if (Module *Mod = ImportD->getImportedModule())
3472f4a2713aSLionel Sambuc return cxstring::createDup(Mod->getFullModuleName());
3473f4a2713aSLionel Sambuc
3474f4a2713aSLionel Sambuc return cxstring::createEmpty();
3475f4a2713aSLionel Sambuc }
3476f4a2713aSLionel Sambuc
3477f4a2713aSLionel Sambuc if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
3478f4a2713aSLionel Sambuc return cxstring::createDup(OMD->getSelector().getAsString());
3479f4a2713aSLionel Sambuc
3480f4a2713aSLionel Sambuc if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
3481f4a2713aSLionel Sambuc // No, this isn't the same as the code below. getIdentifier() is non-virtual
3482f4a2713aSLionel Sambuc // and returns different names. NamedDecl returns the class name and
3483f4a2713aSLionel Sambuc // ObjCCategoryImplDecl returns the category name.
3484f4a2713aSLionel Sambuc return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
3485f4a2713aSLionel Sambuc
3486f4a2713aSLionel Sambuc if (isa<UsingDirectiveDecl>(D))
3487f4a2713aSLionel Sambuc return cxstring::createEmpty();
3488f4a2713aSLionel Sambuc
3489f4a2713aSLionel Sambuc SmallString<1024> S;
3490f4a2713aSLionel Sambuc llvm::raw_svector_ostream os(S);
3491f4a2713aSLionel Sambuc ND->printName(os);
3492f4a2713aSLionel Sambuc
3493f4a2713aSLionel Sambuc return cxstring::createDup(os.str());
3494f4a2713aSLionel Sambuc }
3495f4a2713aSLionel Sambuc
clang_getCursorSpelling(CXCursor C)3496f4a2713aSLionel Sambuc CXString clang_getCursorSpelling(CXCursor C) {
3497f4a2713aSLionel Sambuc if (clang_isTranslationUnit(C.kind))
3498f4a2713aSLionel Sambuc return clang_getTranslationUnitSpelling(getCursorTU(C));
3499f4a2713aSLionel Sambuc
3500f4a2713aSLionel Sambuc if (clang_isReference(C.kind)) {
3501f4a2713aSLionel Sambuc switch (C.kind) {
3502f4a2713aSLionel Sambuc case CXCursor_ObjCSuperClassRef: {
3503f4a2713aSLionel Sambuc const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
3504f4a2713aSLionel Sambuc return cxstring::createRef(Super->getIdentifier()->getNameStart());
3505f4a2713aSLionel Sambuc }
3506f4a2713aSLionel Sambuc case CXCursor_ObjCClassRef: {
3507f4a2713aSLionel Sambuc const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
3508f4a2713aSLionel Sambuc return cxstring::createRef(Class->getIdentifier()->getNameStart());
3509f4a2713aSLionel Sambuc }
3510f4a2713aSLionel Sambuc case CXCursor_ObjCProtocolRef: {
3511f4a2713aSLionel Sambuc const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
3512f4a2713aSLionel Sambuc assert(OID && "getCursorSpelling(): Missing protocol decl");
3513f4a2713aSLionel Sambuc return cxstring::createRef(OID->getIdentifier()->getNameStart());
3514f4a2713aSLionel Sambuc }
3515f4a2713aSLionel Sambuc case CXCursor_CXXBaseSpecifier: {
3516f4a2713aSLionel Sambuc const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3517f4a2713aSLionel Sambuc return cxstring::createDup(B->getType().getAsString());
3518f4a2713aSLionel Sambuc }
3519f4a2713aSLionel Sambuc case CXCursor_TypeRef: {
3520f4a2713aSLionel Sambuc const TypeDecl *Type = getCursorTypeRef(C).first;
3521f4a2713aSLionel Sambuc assert(Type && "Missing type decl");
3522f4a2713aSLionel Sambuc
3523f4a2713aSLionel Sambuc return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
3524f4a2713aSLionel Sambuc getAsString());
3525f4a2713aSLionel Sambuc }
3526f4a2713aSLionel Sambuc case CXCursor_TemplateRef: {
3527f4a2713aSLionel Sambuc const TemplateDecl *Template = getCursorTemplateRef(C).first;
3528f4a2713aSLionel Sambuc assert(Template && "Missing template decl");
3529f4a2713aSLionel Sambuc
3530f4a2713aSLionel Sambuc return cxstring::createDup(Template->getNameAsString());
3531f4a2713aSLionel Sambuc }
3532f4a2713aSLionel Sambuc
3533f4a2713aSLionel Sambuc case CXCursor_NamespaceRef: {
3534f4a2713aSLionel Sambuc const NamedDecl *NS = getCursorNamespaceRef(C).first;
3535f4a2713aSLionel Sambuc assert(NS && "Missing namespace decl");
3536f4a2713aSLionel Sambuc
3537f4a2713aSLionel Sambuc return cxstring::createDup(NS->getNameAsString());
3538f4a2713aSLionel Sambuc }
3539f4a2713aSLionel Sambuc
3540f4a2713aSLionel Sambuc case CXCursor_MemberRef: {
3541f4a2713aSLionel Sambuc const FieldDecl *Field = getCursorMemberRef(C).first;
3542f4a2713aSLionel Sambuc assert(Field && "Missing member decl");
3543f4a2713aSLionel Sambuc
3544f4a2713aSLionel Sambuc return cxstring::createDup(Field->getNameAsString());
3545f4a2713aSLionel Sambuc }
3546f4a2713aSLionel Sambuc
3547f4a2713aSLionel Sambuc case CXCursor_LabelRef: {
3548f4a2713aSLionel Sambuc const LabelStmt *Label = getCursorLabelRef(C).first;
3549f4a2713aSLionel Sambuc assert(Label && "Missing label");
3550f4a2713aSLionel Sambuc
3551f4a2713aSLionel Sambuc return cxstring::createRef(Label->getName());
3552f4a2713aSLionel Sambuc }
3553f4a2713aSLionel Sambuc
3554f4a2713aSLionel Sambuc case CXCursor_OverloadedDeclRef: {
3555f4a2713aSLionel Sambuc OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3556f4a2713aSLionel Sambuc if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3557f4a2713aSLionel Sambuc if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
3558f4a2713aSLionel Sambuc return cxstring::createDup(ND->getNameAsString());
3559f4a2713aSLionel Sambuc return cxstring::createEmpty();
3560f4a2713aSLionel Sambuc }
3561f4a2713aSLionel Sambuc if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
3562f4a2713aSLionel Sambuc return cxstring::createDup(E->getName().getAsString());
3563f4a2713aSLionel Sambuc OverloadedTemplateStorage *Ovl
3564f4a2713aSLionel Sambuc = Storage.get<OverloadedTemplateStorage*>();
3565f4a2713aSLionel Sambuc if (Ovl->size() == 0)
3566f4a2713aSLionel Sambuc return cxstring::createEmpty();
3567f4a2713aSLionel Sambuc return cxstring::createDup((*Ovl->begin())->getNameAsString());
3568f4a2713aSLionel Sambuc }
3569f4a2713aSLionel Sambuc
3570f4a2713aSLionel Sambuc case CXCursor_VariableRef: {
3571f4a2713aSLionel Sambuc const VarDecl *Var = getCursorVariableRef(C).first;
3572f4a2713aSLionel Sambuc assert(Var && "Missing variable decl");
3573f4a2713aSLionel Sambuc
3574f4a2713aSLionel Sambuc return cxstring::createDup(Var->getNameAsString());
3575f4a2713aSLionel Sambuc }
3576f4a2713aSLionel Sambuc
3577f4a2713aSLionel Sambuc default:
3578f4a2713aSLionel Sambuc return cxstring::createRef("<not implemented>");
3579f4a2713aSLionel Sambuc }
3580f4a2713aSLionel Sambuc }
3581f4a2713aSLionel Sambuc
3582f4a2713aSLionel Sambuc if (clang_isExpression(C.kind)) {
3583*0a6a1f1dSLionel Sambuc const Expr *E = getCursorExpr(C);
3584*0a6a1f1dSLionel Sambuc
3585*0a6a1f1dSLionel Sambuc if (C.kind == CXCursor_ObjCStringLiteral ||
3586*0a6a1f1dSLionel Sambuc C.kind == CXCursor_StringLiteral) {
3587*0a6a1f1dSLionel Sambuc const StringLiteral *SLit;
3588*0a6a1f1dSLionel Sambuc if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3589*0a6a1f1dSLionel Sambuc SLit = OSL->getString();
3590*0a6a1f1dSLionel Sambuc } else {
3591*0a6a1f1dSLionel Sambuc SLit = cast<StringLiteral>(E);
3592*0a6a1f1dSLionel Sambuc }
3593*0a6a1f1dSLionel Sambuc SmallString<256> Buf;
3594*0a6a1f1dSLionel Sambuc llvm::raw_svector_ostream OS(Buf);
3595*0a6a1f1dSLionel Sambuc SLit->outputString(OS);
3596*0a6a1f1dSLionel Sambuc return cxstring::createDup(OS.str());
3597*0a6a1f1dSLionel Sambuc }
3598*0a6a1f1dSLionel Sambuc
3599f4a2713aSLionel Sambuc const Decl *D = getDeclFromExpr(getCursorExpr(C));
3600f4a2713aSLionel Sambuc if (D)
3601f4a2713aSLionel Sambuc return getDeclSpelling(D);
3602f4a2713aSLionel Sambuc return cxstring::createEmpty();
3603f4a2713aSLionel Sambuc }
3604f4a2713aSLionel Sambuc
3605f4a2713aSLionel Sambuc if (clang_isStatement(C.kind)) {
3606f4a2713aSLionel Sambuc const Stmt *S = getCursorStmt(C);
3607f4a2713aSLionel Sambuc if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
3608f4a2713aSLionel Sambuc return cxstring::createRef(Label->getName());
3609f4a2713aSLionel Sambuc
3610f4a2713aSLionel Sambuc return cxstring::createEmpty();
3611f4a2713aSLionel Sambuc }
3612f4a2713aSLionel Sambuc
3613f4a2713aSLionel Sambuc if (C.kind == CXCursor_MacroExpansion)
3614f4a2713aSLionel Sambuc return cxstring::createRef(getCursorMacroExpansion(C).getName()
3615f4a2713aSLionel Sambuc ->getNameStart());
3616f4a2713aSLionel Sambuc
3617f4a2713aSLionel Sambuc if (C.kind == CXCursor_MacroDefinition)
3618f4a2713aSLionel Sambuc return cxstring::createRef(getCursorMacroDefinition(C)->getName()
3619f4a2713aSLionel Sambuc ->getNameStart());
3620f4a2713aSLionel Sambuc
3621f4a2713aSLionel Sambuc if (C.kind == CXCursor_InclusionDirective)
3622f4a2713aSLionel Sambuc return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
3623f4a2713aSLionel Sambuc
3624f4a2713aSLionel Sambuc if (clang_isDeclaration(C.kind))
3625f4a2713aSLionel Sambuc return getDeclSpelling(getCursorDecl(C));
3626f4a2713aSLionel Sambuc
3627f4a2713aSLionel Sambuc if (C.kind == CXCursor_AnnotateAttr) {
3628f4a2713aSLionel Sambuc const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
3629f4a2713aSLionel Sambuc return cxstring::createDup(AA->getAnnotation());
3630f4a2713aSLionel Sambuc }
3631f4a2713aSLionel Sambuc
3632f4a2713aSLionel Sambuc if (C.kind == CXCursor_AsmLabelAttr) {
3633f4a2713aSLionel Sambuc const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
3634f4a2713aSLionel Sambuc return cxstring::createDup(AA->getLabel());
3635f4a2713aSLionel Sambuc }
3636f4a2713aSLionel Sambuc
3637f4a2713aSLionel Sambuc if (C.kind == CXCursor_PackedAttr) {
3638f4a2713aSLionel Sambuc return cxstring::createRef("packed");
3639f4a2713aSLionel Sambuc }
3640f4a2713aSLionel Sambuc
3641f4a2713aSLionel Sambuc return cxstring::createEmpty();
3642f4a2713aSLionel Sambuc }
3643f4a2713aSLionel Sambuc
clang_Cursor_getSpellingNameRange(CXCursor C,unsigned pieceIndex,unsigned options)3644f4a2713aSLionel Sambuc CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3645f4a2713aSLionel Sambuc unsigned pieceIndex,
3646f4a2713aSLionel Sambuc unsigned options) {
3647f4a2713aSLionel Sambuc if (clang_Cursor_isNull(C))
3648f4a2713aSLionel Sambuc return clang_getNullRange();
3649f4a2713aSLionel Sambuc
3650f4a2713aSLionel Sambuc ASTContext &Ctx = getCursorContext(C);
3651f4a2713aSLionel Sambuc
3652f4a2713aSLionel Sambuc if (clang_isStatement(C.kind)) {
3653f4a2713aSLionel Sambuc const Stmt *S = getCursorStmt(C);
3654f4a2713aSLionel Sambuc if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
3655f4a2713aSLionel Sambuc if (pieceIndex > 0)
3656f4a2713aSLionel Sambuc return clang_getNullRange();
3657f4a2713aSLionel Sambuc return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3658f4a2713aSLionel Sambuc }
3659f4a2713aSLionel Sambuc
3660f4a2713aSLionel Sambuc return clang_getNullRange();
3661f4a2713aSLionel Sambuc }
3662f4a2713aSLionel Sambuc
3663f4a2713aSLionel Sambuc if (C.kind == CXCursor_ObjCMessageExpr) {
3664f4a2713aSLionel Sambuc if (const ObjCMessageExpr *
3665f4a2713aSLionel Sambuc ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3666f4a2713aSLionel Sambuc if (pieceIndex >= ME->getNumSelectorLocs())
3667f4a2713aSLionel Sambuc return clang_getNullRange();
3668f4a2713aSLionel Sambuc return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3669f4a2713aSLionel Sambuc }
3670f4a2713aSLionel Sambuc }
3671f4a2713aSLionel Sambuc
3672f4a2713aSLionel Sambuc if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3673f4a2713aSLionel Sambuc C.kind == CXCursor_ObjCClassMethodDecl) {
3674f4a2713aSLionel Sambuc if (const ObjCMethodDecl *
3675f4a2713aSLionel Sambuc MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3676f4a2713aSLionel Sambuc if (pieceIndex >= MD->getNumSelectorLocs())
3677f4a2713aSLionel Sambuc return clang_getNullRange();
3678f4a2713aSLionel Sambuc return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3679f4a2713aSLionel Sambuc }
3680f4a2713aSLionel Sambuc }
3681f4a2713aSLionel Sambuc
3682f4a2713aSLionel Sambuc if (C.kind == CXCursor_ObjCCategoryDecl ||
3683f4a2713aSLionel Sambuc C.kind == CXCursor_ObjCCategoryImplDecl) {
3684f4a2713aSLionel Sambuc if (pieceIndex > 0)
3685f4a2713aSLionel Sambuc return clang_getNullRange();
3686f4a2713aSLionel Sambuc if (const ObjCCategoryDecl *
3687f4a2713aSLionel Sambuc CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3688f4a2713aSLionel Sambuc return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
3689f4a2713aSLionel Sambuc if (const ObjCCategoryImplDecl *
3690f4a2713aSLionel Sambuc CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3691f4a2713aSLionel Sambuc return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3692f4a2713aSLionel Sambuc }
3693f4a2713aSLionel Sambuc
3694f4a2713aSLionel Sambuc if (C.kind == CXCursor_ModuleImportDecl) {
3695f4a2713aSLionel Sambuc if (pieceIndex > 0)
3696f4a2713aSLionel Sambuc return clang_getNullRange();
3697f4a2713aSLionel Sambuc if (const ImportDecl *ImportD =
3698f4a2713aSLionel Sambuc dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
3699f4a2713aSLionel Sambuc ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3700f4a2713aSLionel Sambuc if (!Locs.empty())
3701f4a2713aSLionel Sambuc return cxloc::translateSourceRange(Ctx,
3702f4a2713aSLionel Sambuc SourceRange(Locs.front(), Locs.back()));
3703f4a2713aSLionel Sambuc }
3704f4a2713aSLionel Sambuc return clang_getNullRange();
3705f4a2713aSLionel Sambuc }
3706f4a2713aSLionel Sambuc
3707*0a6a1f1dSLionel Sambuc if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3708*0a6a1f1dSLionel Sambuc C.kind == CXCursor_ConversionFunction) {
3709*0a6a1f1dSLionel Sambuc if (pieceIndex > 0)
3710*0a6a1f1dSLionel Sambuc return clang_getNullRange();
3711*0a6a1f1dSLionel Sambuc if (const FunctionDecl *FD =
3712*0a6a1f1dSLionel Sambuc dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3713*0a6a1f1dSLionel Sambuc DeclarationNameInfo FunctionName = FD->getNameInfo();
3714*0a6a1f1dSLionel Sambuc return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3715*0a6a1f1dSLionel Sambuc }
3716*0a6a1f1dSLionel Sambuc return clang_getNullRange();
3717*0a6a1f1dSLionel Sambuc }
3718*0a6a1f1dSLionel Sambuc
3719f4a2713aSLionel Sambuc // FIXME: A CXCursor_InclusionDirective should give the location of the
3720f4a2713aSLionel Sambuc // filename, but we don't keep track of this.
3721f4a2713aSLionel Sambuc
3722f4a2713aSLionel Sambuc // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3723f4a2713aSLionel Sambuc // but we don't keep track of this.
3724f4a2713aSLionel Sambuc
3725f4a2713aSLionel Sambuc // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3726f4a2713aSLionel Sambuc // but we don't keep track of this.
3727f4a2713aSLionel Sambuc
3728f4a2713aSLionel Sambuc // Default handling, give the location of the cursor.
3729f4a2713aSLionel Sambuc
3730f4a2713aSLionel Sambuc if (pieceIndex > 0)
3731f4a2713aSLionel Sambuc return clang_getNullRange();
3732f4a2713aSLionel Sambuc
3733f4a2713aSLionel Sambuc CXSourceLocation CXLoc = clang_getCursorLocation(C);
3734f4a2713aSLionel Sambuc SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3735f4a2713aSLionel Sambuc return cxloc::translateSourceRange(Ctx, Loc);
3736f4a2713aSLionel Sambuc }
3737f4a2713aSLionel Sambuc
clang_Cursor_getMangling(CXCursor C)3738*0a6a1f1dSLionel Sambuc CXString clang_Cursor_getMangling(CXCursor C) {
3739*0a6a1f1dSLionel Sambuc if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3740*0a6a1f1dSLionel Sambuc return cxstring::createEmpty();
3741*0a6a1f1dSLionel Sambuc
3742*0a6a1f1dSLionel Sambuc // Mangling only works for functions and variables.
3743*0a6a1f1dSLionel Sambuc const Decl *D = getCursorDecl(C);
3744*0a6a1f1dSLionel Sambuc if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3745*0a6a1f1dSLionel Sambuc return cxstring::createEmpty();
3746*0a6a1f1dSLionel Sambuc
3747*0a6a1f1dSLionel Sambuc // First apply frontend mangling.
3748*0a6a1f1dSLionel Sambuc const NamedDecl *ND = cast<NamedDecl>(D);
3749*0a6a1f1dSLionel Sambuc ASTContext &Ctx = ND->getASTContext();
3750*0a6a1f1dSLionel Sambuc std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
3751*0a6a1f1dSLionel Sambuc
3752*0a6a1f1dSLionel Sambuc std::string FrontendBuf;
3753*0a6a1f1dSLionel Sambuc llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3754*0a6a1f1dSLionel Sambuc MC->mangleName(ND, FrontendBufOS);
3755*0a6a1f1dSLionel Sambuc
3756*0a6a1f1dSLionel Sambuc // Now apply backend mangling.
3757*0a6a1f1dSLionel Sambuc std::unique_ptr<llvm::DataLayout> DL(
3758*0a6a1f1dSLionel Sambuc new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3759*0a6a1f1dSLionel Sambuc llvm::Mangler BackendMangler(DL.get());
3760*0a6a1f1dSLionel Sambuc
3761*0a6a1f1dSLionel Sambuc std::string FinalBuf;
3762*0a6a1f1dSLionel Sambuc llvm::raw_string_ostream FinalBufOS(FinalBuf);
3763*0a6a1f1dSLionel Sambuc BackendMangler.getNameWithPrefix(FinalBufOS,
3764*0a6a1f1dSLionel Sambuc llvm::Twine(FrontendBufOS.str()));
3765*0a6a1f1dSLionel Sambuc
3766*0a6a1f1dSLionel Sambuc return cxstring::createDup(FinalBufOS.str());
3767*0a6a1f1dSLionel Sambuc }
3768*0a6a1f1dSLionel Sambuc
clang_getCursorDisplayName(CXCursor C)3769f4a2713aSLionel Sambuc CXString clang_getCursorDisplayName(CXCursor C) {
3770f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
3771f4a2713aSLionel Sambuc return clang_getCursorSpelling(C);
3772f4a2713aSLionel Sambuc
3773f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(C);
3774f4a2713aSLionel Sambuc if (!D)
3775f4a2713aSLionel Sambuc return cxstring::createEmpty();
3776f4a2713aSLionel Sambuc
3777f4a2713aSLionel Sambuc PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
3778f4a2713aSLionel Sambuc if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3779f4a2713aSLionel Sambuc D = FunTmpl->getTemplatedDecl();
3780f4a2713aSLionel Sambuc
3781f4a2713aSLionel Sambuc if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3782f4a2713aSLionel Sambuc SmallString<64> Str;
3783f4a2713aSLionel Sambuc llvm::raw_svector_ostream OS(Str);
3784f4a2713aSLionel Sambuc OS << *Function;
3785f4a2713aSLionel Sambuc if (Function->getPrimaryTemplate())
3786f4a2713aSLionel Sambuc OS << "<>";
3787f4a2713aSLionel Sambuc OS << "(";
3788f4a2713aSLionel Sambuc for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3789f4a2713aSLionel Sambuc if (I)
3790f4a2713aSLionel Sambuc OS << ", ";
3791f4a2713aSLionel Sambuc OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3792f4a2713aSLionel Sambuc }
3793f4a2713aSLionel Sambuc
3794f4a2713aSLionel Sambuc if (Function->isVariadic()) {
3795f4a2713aSLionel Sambuc if (Function->getNumParams())
3796f4a2713aSLionel Sambuc OS << ", ";
3797f4a2713aSLionel Sambuc OS << "...";
3798f4a2713aSLionel Sambuc }
3799f4a2713aSLionel Sambuc OS << ")";
3800f4a2713aSLionel Sambuc return cxstring::createDup(OS.str());
3801f4a2713aSLionel Sambuc }
3802f4a2713aSLionel Sambuc
3803f4a2713aSLionel Sambuc if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3804f4a2713aSLionel Sambuc SmallString<64> Str;
3805f4a2713aSLionel Sambuc llvm::raw_svector_ostream OS(Str);
3806f4a2713aSLionel Sambuc OS << *ClassTemplate;
3807f4a2713aSLionel Sambuc OS << "<";
3808f4a2713aSLionel Sambuc TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3809f4a2713aSLionel Sambuc for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3810f4a2713aSLionel Sambuc if (I)
3811f4a2713aSLionel Sambuc OS << ", ";
3812f4a2713aSLionel Sambuc
3813f4a2713aSLionel Sambuc NamedDecl *Param = Params->getParam(I);
3814f4a2713aSLionel Sambuc if (Param->getIdentifier()) {
3815f4a2713aSLionel Sambuc OS << Param->getIdentifier()->getName();
3816f4a2713aSLionel Sambuc continue;
3817f4a2713aSLionel Sambuc }
3818f4a2713aSLionel Sambuc
3819f4a2713aSLionel Sambuc // There is no parameter name, which makes this tricky. Try to come up
3820f4a2713aSLionel Sambuc // with something useful that isn't too long.
3821f4a2713aSLionel Sambuc if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3822f4a2713aSLionel Sambuc OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3823f4a2713aSLionel Sambuc else if (NonTypeTemplateParmDecl *NTTP
3824f4a2713aSLionel Sambuc = dyn_cast<NonTypeTemplateParmDecl>(Param))
3825f4a2713aSLionel Sambuc OS << NTTP->getType().getAsString(Policy);
3826f4a2713aSLionel Sambuc else
3827f4a2713aSLionel Sambuc OS << "template<...> class";
3828f4a2713aSLionel Sambuc }
3829f4a2713aSLionel Sambuc
3830f4a2713aSLionel Sambuc OS << ">";
3831f4a2713aSLionel Sambuc return cxstring::createDup(OS.str());
3832f4a2713aSLionel Sambuc }
3833f4a2713aSLionel Sambuc
3834f4a2713aSLionel Sambuc if (const ClassTemplateSpecializationDecl *ClassSpec
3835f4a2713aSLionel Sambuc = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3836f4a2713aSLionel Sambuc // If the type was explicitly written, use that.
3837f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3838f4a2713aSLionel Sambuc return cxstring::createDup(TSInfo->getType().getAsString(Policy));
3839f4a2713aSLionel Sambuc
3840f4a2713aSLionel Sambuc SmallString<128> Str;
3841f4a2713aSLionel Sambuc llvm::raw_svector_ostream OS(Str);
3842f4a2713aSLionel Sambuc OS << *ClassSpec;
3843f4a2713aSLionel Sambuc TemplateSpecializationType::PrintTemplateArgumentList(OS,
3844f4a2713aSLionel Sambuc ClassSpec->getTemplateArgs().data(),
3845f4a2713aSLionel Sambuc ClassSpec->getTemplateArgs().size(),
3846f4a2713aSLionel Sambuc Policy);
3847f4a2713aSLionel Sambuc return cxstring::createDup(OS.str());
3848f4a2713aSLionel Sambuc }
3849f4a2713aSLionel Sambuc
3850f4a2713aSLionel Sambuc return clang_getCursorSpelling(C);
3851f4a2713aSLionel Sambuc }
3852f4a2713aSLionel Sambuc
clang_getCursorKindSpelling(enum CXCursorKind Kind)3853f4a2713aSLionel Sambuc CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3854f4a2713aSLionel Sambuc switch (Kind) {
3855f4a2713aSLionel Sambuc case CXCursor_FunctionDecl:
3856f4a2713aSLionel Sambuc return cxstring::createRef("FunctionDecl");
3857f4a2713aSLionel Sambuc case CXCursor_TypedefDecl:
3858f4a2713aSLionel Sambuc return cxstring::createRef("TypedefDecl");
3859f4a2713aSLionel Sambuc case CXCursor_EnumDecl:
3860f4a2713aSLionel Sambuc return cxstring::createRef("EnumDecl");
3861f4a2713aSLionel Sambuc case CXCursor_EnumConstantDecl:
3862f4a2713aSLionel Sambuc return cxstring::createRef("EnumConstantDecl");
3863f4a2713aSLionel Sambuc case CXCursor_StructDecl:
3864f4a2713aSLionel Sambuc return cxstring::createRef("StructDecl");
3865f4a2713aSLionel Sambuc case CXCursor_UnionDecl:
3866f4a2713aSLionel Sambuc return cxstring::createRef("UnionDecl");
3867f4a2713aSLionel Sambuc case CXCursor_ClassDecl:
3868f4a2713aSLionel Sambuc return cxstring::createRef("ClassDecl");
3869f4a2713aSLionel Sambuc case CXCursor_FieldDecl:
3870f4a2713aSLionel Sambuc return cxstring::createRef("FieldDecl");
3871f4a2713aSLionel Sambuc case CXCursor_VarDecl:
3872f4a2713aSLionel Sambuc return cxstring::createRef("VarDecl");
3873f4a2713aSLionel Sambuc case CXCursor_ParmDecl:
3874f4a2713aSLionel Sambuc return cxstring::createRef("ParmDecl");
3875f4a2713aSLionel Sambuc case CXCursor_ObjCInterfaceDecl:
3876f4a2713aSLionel Sambuc return cxstring::createRef("ObjCInterfaceDecl");
3877f4a2713aSLionel Sambuc case CXCursor_ObjCCategoryDecl:
3878f4a2713aSLionel Sambuc return cxstring::createRef("ObjCCategoryDecl");
3879f4a2713aSLionel Sambuc case CXCursor_ObjCProtocolDecl:
3880f4a2713aSLionel Sambuc return cxstring::createRef("ObjCProtocolDecl");
3881f4a2713aSLionel Sambuc case CXCursor_ObjCPropertyDecl:
3882f4a2713aSLionel Sambuc return cxstring::createRef("ObjCPropertyDecl");
3883f4a2713aSLionel Sambuc case CXCursor_ObjCIvarDecl:
3884f4a2713aSLionel Sambuc return cxstring::createRef("ObjCIvarDecl");
3885f4a2713aSLionel Sambuc case CXCursor_ObjCInstanceMethodDecl:
3886f4a2713aSLionel Sambuc return cxstring::createRef("ObjCInstanceMethodDecl");
3887f4a2713aSLionel Sambuc case CXCursor_ObjCClassMethodDecl:
3888f4a2713aSLionel Sambuc return cxstring::createRef("ObjCClassMethodDecl");
3889f4a2713aSLionel Sambuc case CXCursor_ObjCImplementationDecl:
3890f4a2713aSLionel Sambuc return cxstring::createRef("ObjCImplementationDecl");
3891f4a2713aSLionel Sambuc case CXCursor_ObjCCategoryImplDecl:
3892f4a2713aSLionel Sambuc return cxstring::createRef("ObjCCategoryImplDecl");
3893f4a2713aSLionel Sambuc case CXCursor_CXXMethod:
3894f4a2713aSLionel Sambuc return cxstring::createRef("CXXMethod");
3895f4a2713aSLionel Sambuc case CXCursor_UnexposedDecl:
3896f4a2713aSLionel Sambuc return cxstring::createRef("UnexposedDecl");
3897f4a2713aSLionel Sambuc case CXCursor_ObjCSuperClassRef:
3898f4a2713aSLionel Sambuc return cxstring::createRef("ObjCSuperClassRef");
3899f4a2713aSLionel Sambuc case CXCursor_ObjCProtocolRef:
3900f4a2713aSLionel Sambuc return cxstring::createRef("ObjCProtocolRef");
3901f4a2713aSLionel Sambuc case CXCursor_ObjCClassRef:
3902f4a2713aSLionel Sambuc return cxstring::createRef("ObjCClassRef");
3903f4a2713aSLionel Sambuc case CXCursor_TypeRef:
3904f4a2713aSLionel Sambuc return cxstring::createRef("TypeRef");
3905f4a2713aSLionel Sambuc case CXCursor_TemplateRef:
3906f4a2713aSLionel Sambuc return cxstring::createRef("TemplateRef");
3907f4a2713aSLionel Sambuc case CXCursor_NamespaceRef:
3908f4a2713aSLionel Sambuc return cxstring::createRef("NamespaceRef");
3909f4a2713aSLionel Sambuc case CXCursor_MemberRef:
3910f4a2713aSLionel Sambuc return cxstring::createRef("MemberRef");
3911f4a2713aSLionel Sambuc case CXCursor_LabelRef:
3912f4a2713aSLionel Sambuc return cxstring::createRef("LabelRef");
3913f4a2713aSLionel Sambuc case CXCursor_OverloadedDeclRef:
3914f4a2713aSLionel Sambuc return cxstring::createRef("OverloadedDeclRef");
3915f4a2713aSLionel Sambuc case CXCursor_VariableRef:
3916f4a2713aSLionel Sambuc return cxstring::createRef("VariableRef");
3917f4a2713aSLionel Sambuc case CXCursor_IntegerLiteral:
3918f4a2713aSLionel Sambuc return cxstring::createRef("IntegerLiteral");
3919f4a2713aSLionel Sambuc case CXCursor_FloatingLiteral:
3920f4a2713aSLionel Sambuc return cxstring::createRef("FloatingLiteral");
3921f4a2713aSLionel Sambuc case CXCursor_ImaginaryLiteral:
3922f4a2713aSLionel Sambuc return cxstring::createRef("ImaginaryLiteral");
3923f4a2713aSLionel Sambuc case CXCursor_StringLiteral:
3924f4a2713aSLionel Sambuc return cxstring::createRef("StringLiteral");
3925f4a2713aSLionel Sambuc case CXCursor_CharacterLiteral:
3926f4a2713aSLionel Sambuc return cxstring::createRef("CharacterLiteral");
3927f4a2713aSLionel Sambuc case CXCursor_ParenExpr:
3928f4a2713aSLionel Sambuc return cxstring::createRef("ParenExpr");
3929f4a2713aSLionel Sambuc case CXCursor_UnaryOperator:
3930f4a2713aSLionel Sambuc return cxstring::createRef("UnaryOperator");
3931f4a2713aSLionel Sambuc case CXCursor_ArraySubscriptExpr:
3932f4a2713aSLionel Sambuc return cxstring::createRef("ArraySubscriptExpr");
3933f4a2713aSLionel Sambuc case CXCursor_BinaryOperator:
3934f4a2713aSLionel Sambuc return cxstring::createRef("BinaryOperator");
3935f4a2713aSLionel Sambuc case CXCursor_CompoundAssignOperator:
3936f4a2713aSLionel Sambuc return cxstring::createRef("CompoundAssignOperator");
3937f4a2713aSLionel Sambuc case CXCursor_ConditionalOperator:
3938f4a2713aSLionel Sambuc return cxstring::createRef("ConditionalOperator");
3939f4a2713aSLionel Sambuc case CXCursor_CStyleCastExpr:
3940f4a2713aSLionel Sambuc return cxstring::createRef("CStyleCastExpr");
3941f4a2713aSLionel Sambuc case CXCursor_CompoundLiteralExpr:
3942f4a2713aSLionel Sambuc return cxstring::createRef("CompoundLiteralExpr");
3943f4a2713aSLionel Sambuc case CXCursor_InitListExpr:
3944f4a2713aSLionel Sambuc return cxstring::createRef("InitListExpr");
3945f4a2713aSLionel Sambuc case CXCursor_AddrLabelExpr:
3946f4a2713aSLionel Sambuc return cxstring::createRef("AddrLabelExpr");
3947f4a2713aSLionel Sambuc case CXCursor_StmtExpr:
3948f4a2713aSLionel Sambuc return cxstring::createRef("StmtExpr");
3949f4a2713aSLionel Sambuc case CXCursor_GenericSelectionExpr:
3950f4a2713aSLionel Sambuc return cxstring::createRef("GenericSelectionExpr");
3951f4a2713aSLionel Sambuc case CXCursor_GNUNullExpr:
3952f4a2713aSLionel Sambuc return cxstring::createRef("GNUNullExpr");
3953f4a2713aSLionel Sambuc case CXCursor_CXXStaticCastExpr:
3954f4a2713aSLionel Sambuc return cxstring::createRef("CXXStaticCastExpr");
3955f4a2713aSLionel Sambuc case CXCursor_CXXDynamicCastExpr:
3956f4a2713aSLionel Sambuc return cxstring::createRef("CXXDynamicCastExpr");
3957f4a2713aSLionel Sambuc case CXCursor_CXXReinterpretCastExpr:
3958f4a2713aSLionel Sambuc return cxstring::createRef("CXXReinterpretCastExpr");
3959f4a2713aSLionel Sambuc case CXCursor_CXXConstCastExpr:
3960f4a2713aSLionel Sambuc return cxstring::createRef("CXXConstCastExpr");
3961f4a2713aSLionel Sambuc case CXCursor_CXXFunctionalCastExpr:
3962f4a2713aSLionel Sambuc return cxstring::createRef("CXXFunctionalCastExpr");
3963f4a2713aSLionel Sambuc case CXCursor_CXXTypeidExpr:
3964f4a2713aSLionel Sambuc return cxstring::createRef("CXXTypeidExpr");
3965f4a2713aSLionel Sambuc case CXCursor_CXXBoolLiteralExpr:
3966f4a2713aSLionel Sambuc return cxstring::createRef("CXXBoolLiteralExpr");
3967f4a2713aSLionel Sambuc case CXCursor_CXXNullPtrLiteralExpr:
3968f4a2713aSLionel Sambuc return cxstring::createRef("CXXNullPtrLiteralExpr");
3969f4a2713aSLionel Sambuc case CXCursor_CXXThisExpr:
3970f4a2713aSLionel Sambuc return cxstring::createRef("CXXThisExpr");
3971f4a2713aSLionel Sambuc case CXCursor_CXXThrowExpr:
3972f4a2713aSLionel Sambuc return cxstring::createRef("CXXThrowExpr");
3973f4a2713aSLionel Sambuc case CXCursor_CXXNewExpr:
3974f4a2713aSLionel Sambuc return cxstring::createRef("CXXNewExpr");
3975f4a2713aSLionel Sambuc case CXCursor_CXXDeleteExpr:
3976f4a2713aSLionel Sambuc return cxstring::createRef("CXXDeleteExpr");
3977f4a2713aSLionel Sambuc case CXCursor_UnaryExpr:
3978f4a2713aSLionel Sambuc return cxstring::createRef("UnaryExpr");
3979f4a2713aSLionel Sambuc case CXCursor_ObjCStringLiteral:
3980f4a2713aSLionel Sambuc return cxstring::createRef("ObjCStringLiteral");
3981f4a2713aSLionel Sambuc case CXCursor_ObjCBoolLiteralExpr:
3982f4a2713aSLionel Sambuc return cxstring::createRef("ObjCBoolLiteralExpr");
3983f4a2713aSLionel Sambuc case CXCursor_ObjCSelfExpr:
3984f4a2713aSLionel Sambuc return cxstring::createRef("ObjCSelfExpr");
3985f4a2713aSLionel Sambuc case CXCursor_ObjCEncodeExpr:
3986f4a2713aSLionel Sambuc return cxstring::createRef("ObjCEncodeExpr");
3987f4a2713aSLionel Sambuc case CXCursor_ObjCSelectorExpr:
3988f4a2713aSLionel Sambuc return cxstring::createRef("ObjCSelectorExpr");
3989f4a2713aSLionel Sambuc case CXCursor_ObjCProtocolExpr:
3990f4a2713aSLionel Sambuc return cxstring::createRef("ObjCProtocolExpr");
3991f4a2713aSLionel Sambuc case CXCursor_ObjCBridgedCastExpr:
3992f4a2713aSLionel Sambuc return cxstring::createRef("ObjCBridgedCastExpr");
3993f4a2713aSLionel Sambuc case CXCursor_BlockExpr:
3994f4a2713aSLionel Sambuc return cxstring::createRef("BlockExpr");
3995f4a2713aSLionel Sambuc case CXCursor_PackExpansionExpr:
3996f4a2713aSLionel Sambuc return cxstring::createRef("PackExpansionExpr");
3997f4a2713aSLionel Sambuc case CXCursor_SizeOfPackExpr:
3998f4a2713aSLionel Sambuc return cxstring::createRef("SizeOfPackExpr");
3999f4a2713aSLionel Sambuc case CXCursor_LambdaExpr:
4000f4a2713aSLionel Sambuc return cxstring::createRef("LambdaExpr");
4001f4a2713aSLionel Sambuc case CXCursor_UnexposedExpr:
4002f4a2713aSLionel Sambuc return cxstring::createRef("UnexposedExpr");
4003f4a2713aSLionel Sambuc case CXCursor_DeclRefExpr:
4004f4a2713aSLionel Sambuc return cxstring::createRef("DeclRefExpr");
4005f4a2713aSLionel Sambuc case CXCursor_MemberRefExpr:
4006f4a2713aSLionel Sambuc return cxstring::createRef("MemberRefExpr");
4007f4a2713aSLionel Sambuc case CXCursor_CallExpr:
4008f4a2713aSLionel Sambuc return cxstring::createRef("CallExpr");
4009f4a2713aSLionel Sambuc case CXCursor_ObjCMessageExpr:
4010f4a2713aSLionel Sambuc return cxstring::createRef("ObjCMessageExpr");
4011f4a2713aSLionel Sambuc case CXCursor_UnexposedStmt:
4012f4a2713aSLionel Sambuc return cxstring::createRef("UnexposedStmt");
4013f4a2713aSLionel Sambuc case CXCursor_DeclStmt:
4014f4a2713aSLionel Sambuc return cxstring::createRef("DeclStmt");
4015f4a2713aSLionel Sambuc case CXCursor_LabelStmt:
4016f4a2713aSLionel Sambuc return cxstring::createRef("LabelStmt");
4017f4a2713aSLionel Sambuc case CXCursor_CompoundStmt:
4018f4a2713aSLionel Sambuc return cxstring::createRef("CompoundStmt");
4019f4a2713aSLionel Sambuc case CXCursor_CaseStmt:
4020f4a2713aSLionel Sambuc return cxstring::createRef("CaseStmt");
4021f4a2713aSLionel Sambuc case CXCursor_DefaultStmt:
4022f4a2713aSLionel Sambuc return cxstring::createRef("DefaultStmt");
4023f4a2713aSLionel Sambuc case CXCursor_IfStmt:
4024f4a2713aSLionel Sambuc return cxstring::createRef("IfStmt");
4025f4a2713aSLionel Sambuc case CXCursor_SwitchStmt:
4026f4a2713aSLionel Sambuc return cxstring::createRef("SwitchStmt");
4027f4a2713aSLionel Sambuc case CXCursor_WhileStmt:
4028f4a2713aSLionel Sambuc return cxstring::createRef("WhileStmt");
4029f4a2713aSLionel Sambuc case CXCursor_DoStmt:
4030f4a2713aSLionel Sambuc return cxstring::createRef("DoStmt");
4031f4a2713aSLionel Sambuc case CXCursor_ForStmt:
4032f4a2713aSLionel Sambuc return cxstring::createRef("ForStmt");
4033f4a2713aSLionel Sambuc case CXCursor_GotoStmt:
4034f4a2713aSLionel Sambuc return cxstring::createRef("GotoStmt");
4035f4a2713aSLionel Sambuc case CXCursor_IndirectGotoStmt:
4036f4a2713aSLionel Sambuc return cxstring::createRef("IndirectGotoStmt");
4037f4a2713aSLionel Sambuc case CXCursor_ContinueStmt:
4038f4a2713aSLionel Sambuc return cxstring::createRef("ContinueStmt");
4039f4a2713aSLionel Sambuc case CXCursor_BreakStmt:
4040f4a2713aSLionel Sambuc return cxstring::createRef("BreakStmt");
4041f4a2713aSLionel Sambuc case CXCursor_ReturnStmt:
4042f4a2713aSLionel Sambuc return cxstring::createRef("ReturnStmt");
4043f4a2713aSLionel Sambuc case CXCursor_GCCAsmStmt:
4044f4a2713aSLionel Sambuc return cxstring::createRef("GCCAsmStmt");
4045f4a2713aSLionel Sambuc case CXCursor_MSAsmStmt:
4046f4a2713aSLionel Sambuc return cxstring::createRef("MSAsmStmt");
4047f4a2713aSLionel Sambuc case CXCursor_ObjCAtTryStmt:
4048f4a2713aSLionel Sambuc return cxstring::createRef("ObjCAtTryStmt");
4049f4a2713aSLionel Sambuc case CXCursor_ObjCAtCatchStmt:
4050f4a2713aSLionel Sambuc return cxstring::createRef("ObjCAtCatchStmt");
4051f4a2713aSLionel Sambuc case CXCursor_ObjCAtFinallyStmt:
4052f4a2713aSLionel Sambuc return cxstring::createRef("ObjCAtFinallyStmt");
4053f4a2713aSLionel Sambuc case CXCursor_ObjCAtThrowStmt:
4054f4a2713aSLionel Sambuc return cxstring::createRef("ObjCAtThrowStmt");
4055f4a2713aSLionel Sambuc case CXCursor_ObjCAtSynchronizedStmt:
4056f4a2713aSLionel Sambuc return cxstring::createRef("ObjCAtSynchronizedStmt");
4057f4a2713aSLionel Sambuc case CXCursor_ObjCAutoreleasePoolStmt:
4058f4a2713aSLionel Sambuc return cxstring::createRef("ObjCAutoreleasePoolStmt");
4059f4a2713aSLionel Sambuc case CXCursor_ObjCForCollectionStmt:
4060f4a2713aSLionel Sambuc return cxstring::createRef("ObjCForCollectionStmt");
4061f4a2713aSLionel Sambuc case CXCursor_CXXCatchStmt:
4062f4a2713aSLionel Sambuc return cxstring::createRef("CXXCatchStmt");
4063f4a2713aSLionel Sambuc case CXCursor_CXXTryStmt:
4064f4a2713aSLionel Sambuc return cxstring::createRef("CXXTryStmt");
4065f4a2713aSLionel Sambuc case CXCursor_CXXForRangeStmt:
4066f4a2713aSLionel Sambuc return cxstring::createRef("CXXForRangeStmt");
4067f4a2713aSLionel Sambuc case CXCursor_SEHTryStmt:
4068f4a2713aSLionel Sambuc return cxstring::createRef("SEHTryStmt");
4069f4a2713aSLionel Sambuc case CXCursor_SEHExceptStmt:
4070f4a2713aSLionel Sambuc return cxstring::createRef("SEHExceptStmt");
4071f4a2713aSLionel Sambuc case CXCursor_SEHFinallyStmt:
4072f4a2713aSLionel Sambuc return cxstring::createRef("SEHFinallyStmt");
4073*0a6a1f1dSLionel Sambuc case CXCursor_SEHLeaveStmt:
4074*0a6a1f1dSLionel Sambuc return cxstring::createRef("SEHLeaveStmt");
4075f4a2713aSLionel Sambuc case CXCursor_NullStmt:
4076f4a2713aSLionel Sambuc return cxstring::createRef("NullStmt");
4077f4a2713aSLionel Sambuc case CXCursor_InvalidFile:
4078f4a2713aSLionel Sambuc return cxstring::createRef("InvalidFile");
4079f4a2713aSLionel Sambuc case CXCursor_InvalidCode:
4080f4a2713aSLionel Sambuc return cxstring::createRef("InvalidCode");
4081f4a2713aSLionel Sambuc case CXCursor_NoDeclFound:
4082f4a2713aSLionel Sambuc return cxstring::createRef("NoDeclFound");
4083f4a2713aSLionel Sambuc case CXCursor_NotImplemented:
4084f4a2713aSLionel Sambuc return cxstring::createRef("NotImplemented");
4085f4a2713aSLionel Sambuc case CXCursor_TranslationUnit:
4086f4a2713aSLionel Sambuc return cxstring::createRef("TranslationUnit");
4087f4a2713aSLionel Sambuc case CXCursor_UnexposedAttr:
4088f4a2713aSLionel Sambuc return cxstring::createRef("UnexposedAttr");
4089f4a2713aSLionel Sambuc case CXCursor_IBActionAttr:
4090f4a2713aSLionel Sambuc return cxstring::createRef("attribute(ibaction)");
4091f4a2713aSLionel Sambuc case CXCursor_IBOutletAttr:
4092f4a2713aSLionel Sambuc return cxstring::createRef("attribute(iboutlet)");
4093f4a2713aSLionel Sambuc case CXCursor_IBOutletCollectionAttr:
4094f4a2713aSLionel Sambuc return cxstring::createRef("attribute(iboutletcollection)");
4095f4a2713aSLionel Sambuc case CXCursor_CXXFinalAttr:
4096f4a2713aSLionel Sambuc return cxstring::createRef("attribute(final)");
4097f4a2713aSLionel Sambuc case CXCursor_CXXOverrideAttr:
4098f4a2713aSLionel Sambuc return cxstring::createRef("attribute(override)");
4099f4a2713aSLionel Sambuc case CXCursor_AnnotateAttr:
4100f4a2713aSLionel Sambuc return cxstring::createRef("attribute(annotate)");
4101f4a2713aSLionel Sambuc case CXCursor_AsmLabelAttr:
4102f4a2713aSLionel Sambuc return cxstring::createRef("asm label");
4103f4a2713aSLionel Sambuc case CXCursor_PackedAttr:
4104f4a2713aSLionel Sambuc return cxstring::createRef("attribute(packed)");
4105*0a6a1f1dSLionel Sambuc case CXCursor_PureAttr:
4106*0a6a1f1dSLionel Sambuc return cxstring::createRef("attribute(pure)");
4107*0a6a1f1dSLionel Sambuc case CXCursor_ConstAttr:
4108*0a6a1f1dSLionel Sambuc return cxstring::createRef("attribute(const)");
4109*0a6a1f1dSLionel Sambuc case CXCursor_NoDuplicateAttr:
4110*0a6a1f1dSLionel Sambuc return cxstring::createRef("attribute(noduplicate)");
4111*0a6a1f1dSLionel Sambuc case CXCursor_CUDAConstantAttr:
4112*0a6a1f1dSLionel Sambuc return cxstring::createRef("attribute(constant)");
4113*0a6a1f1dSLionel Sambuc case CXCursor_CUDADeviceAttr:
4114*0a6a1f1dSLionel Sambuc return cxstring::createRef("attribute(device)");
4115*0a6a1f1dSLionel Sambuc case CXCursor_CUDAGlobalAttr:
4116*0a6a1f1dSLionel Sambuc return cxstring::createRef("attribute(global)");
4117*0a6a1f1dSLionel Sambuc case CXCursor_CUDAHostAttr:
4118*0a6a1f1dSLionel Sambuc return cxstring::createRef("attribute(host)");
4119*0a6a1f1dSLionel Sambuc case CXCursor_CUDASharedAttr:
4120*0a6a1f1dSLionel Sambuc return cxstring::createRef("attribute(shared)");
4121f4a2713aSLionel Sambuc case CXCursor_PreprocessingDirective:
4122f4a2713aSLionel Sambuc return cxstring::createRef("preprocessing directive");
4123f4a2713aSLionel Sambuc case CXCursor_MacroDefinition:
4124f4a2713aSLionel Sambuc return cxstring::createRef("macro definition");
4125f4a2713aSLionel Sambuc case CXCursor_MacroExpansion:
4126f4a2713aSLionel Sambuc return cxstring::createRef("macro expansion");
4127f4a2713aSLionel Sambuc case CXCursor_InclusionDirective:
4128f4a2713aSLionel Sambuc return cxstring::createRef("inclusion directive");
4129f4a2713aSLionel Sambuc case CXCursor_Namespace:
4130f4a2713aSLionel Sambuc return cxstring::createRef("Namespace");
4131f4a2713aSLionel Sambuc case CXCursor_LinkageSpec:
4132f4a2713aSLionel Sambuc return cxstring::createRef("LinkageSpec");
4133f4a2713aSLionel Sambuc case CXCursor_CXXBaseSpecifier:
4134f4a2713aSLionel Sambuc return cxstring::createRef("C++ base class specifier");
4135f4a2713aSLionel Sambuc case CXCursor_Constructor:
4136f4a2713aSLionel Sambuc return cxstring::createRef("CXXConstructor");
4137f4a2713aSLionel Sambuc case CXCursor_Destructor:
4138f4a2713aSLionel Sambuc return cxstring::createRef("CXXDestructor");
4139f4a2713aSLionel Sambuc case CXCursor_ConversionFunction:
4140f4a2713aSLionel Sambuc return cxstring::createRef("CXXConversion");
4141f4a2713aSLionel Sambuc case CXCursor_TemplateTypeParameter:
4142f4a2713aSLionel Sambuc return cxstring::createRef("TemplateTypeParameter");
4143f4a2713aSLionel Sambuc case CXCursor_NonTypeTemplateParameter:
4144f4a2713aSLionel Sambuc return cxstring::createRef("NonTypeTemplateParameter");
4145f4a2713aSLionel Sambuc case CXCursor_TemplateTemplateParameter:
4146f4a2713aSLionel Sambuc return cxstring::createRef("TemplateTemplateParameter");
4147f4a2713aSLionel Sambuc case CXCursor_FunctionTemplate:
4148f4a2713aSLionel Sambuc return cxstring::createRef("FunctionTemplate");
4149f4a2713aSLionel Sambuc case CXCursor_ClassTemplate:
4150f4a2713aSLionel Sambuc return cxstring::createRef("ClassTemplate");
4151f4a2713aSLionel Sambuc case CXCursor_ClassTemplatePartialSpecialization:
4152f4a2713aSLionel Sambuc return cxstring::createRef("ClassTemplatePartialSpecialization");
4153f4a2713aSLionel Sambuc case CXCursor_NamespaceAlias:
4154f4a2713aSLionel Sambuc return cxstring::createRef("NamespaceAlias");
4155f4a2713aSLionel Sambuc case CXCursor_UsingDirective:
4156f4a2713aSLionel Sambuc return cxstring::createRef("UsingDirective");
4157f4a2713aSLionel Sambuc case CXCursor_UsingDeclaration:
4158f4a2713aSLionel Sambuc return cxstring::createRef("UsingDeclaration");
4159f4a2713aSLionel Sambuc case CXCursor_TypeAliasDecl:
4160f4a2713aSLionel Sambuc return cxstring::createRef("TypeAliasDecl");
4161f4a2713aSLionel Sambuc case CXCursor_ObjCSynthesizeDecl:
4162f4a2713aSLionel Sambuc return cxstring::createRef("ObjCSynthesizeDecl");
4163f4a2713aSLionel Sambuc case CXCursor_ObjCDynamicDecl:
4164f4a2713aSLionel Sambuc return cxstring::createRef("ObjCDynamicDecl");
4165f4a2713aSLionel Sambuc case CXCursor_CXXAccessSpecifier:
4166f4a2713aSLionel Sambuc return cxstring::createRef("CXXAccessSpecifier");
4167f4a2713aSLionel Sambuc case CXCursor_ModuleImportDecl:
4168f4a2713aSLionel Sambuc return cxstring::createRef("ModuleImport");
4169f4a2713aSLionel Sambuc case CXCursor_OMPParallelDirective:
4170f4a2713aSLionel Sambuc return cxstring::createRef("OMPParallelDirective");
4171*0a6a1f1dSLionel Sambuc case CXCursor_OMPSimdDirective:
4172*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPSimdDirective");
4173*0a6a1f1dSLionel Sambuc case CXCursor_OMPForDirective:
4174*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPForDirective");
4175*0a6a1f1dSLionel Sambuc case CXCursor_OMPForSimdDirective:
4176*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPForSimdDirective");
4177*0a6a1f1dSLionel Sambuc case CXCursor_OMPSectionsDirective:
4178*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPSectionsDirective");
4179*0a6a1f1dSLionel Sambuc case CXCursor_OMPSectionDirective:
4180*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPSectionDirective");
4181*0a6a1f1dSLionel Sambuc case CXCursor_OMPSingleDirective:
4182*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPSingleDirective");
4183*0a6a1f1dSLionel Sambuc case CXCursor_OMPMasterDirective:
4184*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPMasterDirective");
4185*0a6a1f1dSLionel Sambuc case CXCursor_OMPCriticalDirective:
4186*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPCriticalDirective");
4187*0a6a1f1dSLionel Sambuc case CXCursor_OMPParallelForDirective:
4188*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPParallelForDirective");
4189*0a6a1f1dSLionel Sambuc case CXCursor_OMPParallelForSimdDirective:
4190*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPParallelForSimdDirective");
4191*0a6a1f1dSLionel Sambuc case CXCursor_OMPParallelSectionsDirective:
4192*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPParallelSectionsDirective");
4193*0a6a1f1dSLionel Sambuc case CXCursor_OMPTaskDirective:
4194*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPTaskDirective");
4195*0a6a1f1dSLionel Sambuc case CXCursor_OMPTaskyieldDirective:
4196*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPTaskyieldDirective");
4197*0a6a1f1dSLionel Sambuc case CXCursor_OMPBarrierDirective:
4198*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPBarrierDirective");
4199*0a6a1f1dSLionel Sambuc case CXCursor_OMPTaskwaitDirective:
4200*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPTaskwaitDirective");
4201*0a6a1f1dSLionel Sambuc case CXCursor_OMPFlushDirective:
4202*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPFlushDirective");
4203*0a6a1f1dSLionel Sambuc case CXCursor_OMPOrderedDirective:
4204*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPOrderedDirective");
4205*0a6a1f1dSLionel Sambuc case CXCursor_OMPAtomicDirective:
4206*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPAtomicDirective");
4207*0a6a1f1dSLionel Sambuc case CXCursor_OMPTargetDirective:
4208*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPTargetDirective");
4209*0a6a1f1dSLionel Sambuc case CXCursor_OMPTeamsDirective:
4210*0a6a1f1dSLionel Sambuc return cxstring::createRef("OMPTeamsDirective");
4211f4a2713aSLionel Sambuc }
4212f4a2713aSLionel Sambuc
4213f4a2713aSLionel Sambuc llvm_unreachable("Unhandled CXCursorKind");
4214f4a2713aSLionel Sambuc }
4215f4a2713aSLionel Sambuc
4216f4a2713aSLionel Sambuc struct GetCursorData {
4217f4a2713aSLionel Sambuc SourceLocation TokenBeginLoc;
4218f4a2713aSLionel Sambuc bool PointsAtMacroArgExpansion;
4219f4a2713aSLionel Sambuc bool VisitedObjCPropertyImplDecl;
4220f4a2713aSLionel Sambuc SourceLocation VisitedDeclaratorDeclStartLoc;
4221f4a2713aSLionel Sambuc CXCursor &BestCursor;
4222f4a2713aSLionel Sambuc
GetCursorDataGetCursorData4223f4a2713aSLionel Sambuc GetCursorData(SourceManager &SM,
4224f4a2713aSLionel Sambuc SourceLocation tokenBegin, CXCursor &outputCursor)
4225f4a2713aSLionel Sambuc : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4226f4a2713aSLionel Sambuc PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4227f4a2713aSLionel Sambuc VisitedObjCPropertyImplDecl = false;
4228f4a2713aSLionel Sambuc }
4229f4a2713aSLionel Sambuc };
4230f4a2713aSLionel Sambuc
GetCursorVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)4231f4a2713aSLionel Sambuc static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4232f4a2713aSLionel Sambuc CXCursor parent,
4233f4a2713aSLionel Sambuc CXClientData client_data) {
4234f4a2713aSLionel Sambuc GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4235f4a2713aSLionel Sambuc CXCursor *BestCursor = &Data->BestCursor;
4236f4a2713aSLionel Sambuc
4237f4a2713aSLionel Sambuc // If we point inside a macro argument we should provide info of what the
4238f4a2713aSLionel Sambuc // token is so use the actual cursor, don't replace it with a macro expansion
4239f4a2713aSLionel Sambuc // cursor.
4240f4a2713aSLionel Sambuc if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4241f4a2713aSLionel Sambuc return CXChildVisit_Recurse;
4242f4a2713aSLionel Sambuc
4243f4a2713aSLionel Sambuc if (clang_isDeclaration(cursor.kind)) {
4244f4a2713aSLionel Sambuc // Avoid having the implicit methods override the property decls.
4245f4a2713aSLionel Sambuc if (const ObjCMethodDecl *MD
4246f4a2713aSLionel Sambuc = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4247f4a2713aSLionel Sambuc if (MD->isImplicit())
4248f4a2713aSLionel Sambuc return CXChildVisit_Break;
4249f4a2713aSLionel Sambuc
4250f4a2713aSLionel Sambuc } else if (const ObjCInterfaceDecl *ID
4251f4a2713aSLionel Sambuc = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4252f4a2713aSLionel Sambuc // Check that when we have multiple @class references in the same line,
4253f4a2713aSLionel Sambuc // that later ones do not override the previous ones.
4254f4a2713aSLionel Sambuc // If we have:
4255f4a2713aSLionel Sambuc // @class Foo, Bar;
4256f4a2713aSLionel Sambuc // source ranges for both start at '@', so 'Bar' will end up overriding
4257f4a2713aSLionel Sambuc // 'Foo' even though the cursor location was at 'Foo'.
4258f4a2713aSLionel Sambuc if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4259f4a2713aSLionel Sambuc BestCursor->kind == CXCursor_ObjCClassRef)
4260f4a2713aSLionel Sambuc if (const ObjCInterfaceDecl *PrevID
4261f4a2713aSLionel Sambuc = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4262f4a2713aSLionel Sambuc if (PrevID != ID &&
4263f4a2713aSLionel Sambuc !PrevID->isThisDeclarationADefinition() &&
4264f4a2713aSLionel Sambuc !ID->isThisDeclarationADefinition())
4265f4a2713aSLionel Sambuc return CXChildVisit_Break;
4266f4a2713aSLionel Sambuc }
4267f4a2713aSLionel Sambuc
4268f4a2713aSLionel Sambuc } else if (const DeclaratorDecl *DD
4269f4a2713aSLionel Sambuc = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4270f4a2713aSLionel Sambuc SourceLocation StartLoc = DD->getSourceRange().getBegin();
4271f4a2713aSLionel Sambuc // Check that when we have multiple declarators in the same line,
4272f4a2713aSLionel Sambuc // that later ones do not override the previous ones.
4273f4a2713aSLionel Sambuc // If we have:
4274f4a2713aSLionel Sambuc // int Foo, Bar;
4275f4a2713aSLionel Sambuc // source ranges for both start at 'int', so 'Bar' will end up overriding
4276f4a2713aSLionel Sambuc // 'Foo' even though the cursor location was at 'Foo'.
4277f4a2713aSLionel Sambuc if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4278f4a2713aSLionel Sambuc return CXChildVisit_Break;
4279f4a2713aSLionel Sambuc Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4280f4a2713aSLionel Sambuc
4281f4a2713aSLionel Sambuc } else if (const ObjCPropertyImplDecl *PropImp
4282f4a2713aSLionel Sambuc = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4283f4a2713aSLionel Sambuc (void)PropImp;
4284f4a2713aSLionel Sambuc // Check that when we have multiple @synthesize in the same line,
4285f4a2713aSLionel Sambuc // that later ones do not override the previous ones.
4286f4a2713aSLionel Sambuc // If we have:
4287f4a2713aSLionel Sambuc // @synthesize Foo, Bar;
4288f4a2713aSLionel Sambuc // source ranges for both start at '@', so 'Bar' will end up overriding
4289f4a2713aSLionel Sambuc // 'Foo' even though the cursor location was at 'Foo'.
4290f4a2713aSLionel Sambuc if (Data->VisitedObjCPropertyImplDecl)
4291f4a2713aSLionel Sambuc return CXChildVisit_Break;
4292f4a2713aSLionel Sambuc Data->VisitedObjCPropertyImplDecl = true;
4293f4a2713aSLionel Sambuc }
4294f4a2713aSLionel Sambuc }
4295f4a2713aSLionel Sambuc
4296f4a2713aSLionel Sambuc if (clang_isExpression(cursor.kind) &&
4297f4a2713aSLionel Sambuc clang_isDeclaration(BestCursor->kind)) {
4298f4a2713aSLionel Sambuc if (const Decl *D = getCursorDecl(*BestCursor)) {
4299f4a2713aSLionel Sambuc // Avoid having the cursor of an expression replace the declaration cursor
4300f4a2713aSLionel Sambuc // when the expression source range overlaps the declaration range.
4301f4a2713aSLionel Sambuc // This can happen for C++ constructor expressions whose range generally
4302f4a2713aSLionel Sambuc // include the variable declaration, e.g.:
4303f4a2713aSLionel Sambuc // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4304f4a2713aSLionel Sambuc if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4305f4a2713aSLionel Sambuc D->getLocation() == Data->TokenBeginLoc)
4306f4a2713aSLionel Sambuc return CXChildVisit_Break;
4307f4a2713aSLionel Sambuc }
4308f4a2713aSLionel Sambuc }
4309f4a2713aSLionel Sambuc
4310f4a2713aSLionel Sambuc // If our current best cursor is the construction of a temporary object,
4311f4a2713aSLionel Sambuc // don't replace that cursor with a type reference, because we want
4312f4a2713aSLionel Sambuc // clang_getCursor() to point at the constructor.
4313f4a2713aSLionel Sambuc if (clang_isExpression(BestCursor->kind) &&
4314f4a2713aSLionel Sambuc isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4315f4a2713aSLionel Sambuc cursor.kind == CXCursor_TypeRef) {
4316f4a2713aSLionel Sambuc // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4317f4a2713aSLionel Sambuc // as having the actual point on the type reference.
4318f4a2713aSLionel Sambuc *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4319f4a2713aSLionel Sambuc return CXChildVisit_Recurse;
4320f4a2713aSLionel Sambuc }
4321f4a2713aSLionel Sambuc
4322f4a2713aSLionel Sambuc *BestCursor = cursor;
4323f4a2713aSLionel Sambuc return CXChildVisit_Recurse;
4324f4a2713aSLionel Sambuc }
4325f4a2713aSLionel Sambuc
clang_getCursor(CXTranslationUnit TU,CXSourceLocation Loc)4326f4a2713aSLionel Sambuc CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
4327*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
4328*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
4329f4a2713aSLionel Sambuc return clang_getNullCursor();
4330*0a6a1f1dSLionel Sambuc }
4331f4a2713aSLionel Sambuc
4332f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4333f4a2713aSLionel Sambuc ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4334f4a2713aSLionel Sambuc
4335f4a2713aSLionel Sambuc SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4336f4a2713aSLionel Sambuc CXCursor Result = cxcursor::getCursor(TU, SLoc);
4337f4a2713aSLionel Sambuc
4338f4a2713aSLionel Sambuc LOG_FUNC_SECTION {
4339f4a2713aSLionel Sambuc CXFile SearchFile;
4340f4a2713aSLionel Sambuc unsigned SearchLine, SearchColumn;
4341f4a2713aSLionel Sambuc CXFile ResultFile;
4342f4a2713aSLionel Sambuc unsigned ResultLine, ResultColumn;
4343f4a2713aSLionel Sambuc CXString SearchFileName, ResultFileName, KindSpelling, USR;
4344f4a2713aSLionel Sambuc const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4345f4a2713aSLionel Sambuc CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4346f4a2713aSLionel Sambuc
4347*0a6a1f1dSLionel Sambuc clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4348*0a6a1f1dSLionel Sambuc nullptr);
4349f4a2713aSLionel Sambuc clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
4350*0a6a1f1dSLionel Sambuc &ResultColumn, nullptr);
4351f4a2713aSLionel Sambuc SearchFileName = clang_getFileName(SearchFile);
4352f4a2713aSLionel Sambuc ResultFileName = clang_getFileName(ResultFile);
4353f4a2713aSLionel Sambuc KindSpelling = clang_getCursorKindSpelling(Result.kind);
4354f4a2713aSLionel Sambuc USR = clang_getCursorUSR(Result);
4355f4a2713aSLionel Sambuc *Log << llvm::format("(%s:%d:%d) = %s",
4356f4a2713aSLionel Sambuc clang_getCString(SearchFileName), SearchLine, SearchColumn,
4357f4a2713aSLionel Sambuc clang_getCString(KindSpelling))
4358f4a2713aSLionel Sambuc << llvm::format("(%s:%d:%d):%s%s",
4359f4a2713aSLionel Sambuc clang_getCString(ResultFileName), ResultLine, ResultColumn,
4360f4a2713aSLionel Sambuc clang_getCString(USR), IsDef);
4361f4a2713aSLionel Sambuc clang_disposeString(SearchFileName);
4362f4a2713aSLionel Sambuc clang_disposeString(ResultFileName);
4363f4a2713aSLionel Sambuc clang_disposeString(KindSpelling);
4364f4a2713aSLionel Sambuc clang_disposeString(USR);
4365f4a2713aSLionel Sambuc
4366f4a2713aSLionel Sambuc CXCursor Definition = clang_getCursorDefinition(Result);
4367f4a2713aSLionel Sambuc if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4368f4a2713aSLionel Sambuc CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4369f4a2713aSLionel Sambuc CXString DefinitionKindSpelling
4370f4a2713aSLionel Sambuc = clang_getCursorKindSpelling(Definition.kind);
4371f4a2713aSLionel Sambuc CXFile DefinitionFile;
4372f4a2713aSLionel Sambuc unsigned DefinitionLine, DefinitionColumn;
4373f4a2713aSLionel Sambuc clang_getFileLocation(DefinitionLoc, &DefinitionFile,
4374*0a6a1f1dSLionel Sambuc &DefinitionLine, &DefinitionColumn, nullptr);
4375f4a2713aSLionel Sambuc CXString DefinitionFileName = clang_getFileName(DefinitionFile);
4376f4a2713aSLionel Sambuc *Log << llvm::format(" -> %s(%s:%d:%d)",
4377f4a2713aSLionel Sambuc clang_getCString(DefinitionKindSpelling),
4378f4a2713aSLionel Sambuc clang_getCString(DefinitionFileName),
4379f4a2713aSLionel Sambuc DefinitionLine, DefinitionColumn);
4380f4a2713aSLionel Sambuc clang_disposeString(DefinitionFileName);
4381f4a2713aSLionel Sambuc clang_disposeString(DefinitionKindSpelling);
4382f4a2713aSLionel Sambuc }
4383f4a2713aSLionel Sambuc }
4384f4a2713aSLionel Sambuc
4385f4a2713aSLionel Sambuc return Result;
4386f4a2713aSLionel Sambuc }
4387f4a2713aSLionel Sambuc
clang_getNullCursor(void)4388f4a2713aSLionel Sambuc CXCursor clang_getNullCursor(void) {
4389f4a2713aSLionel Sambuc return MakeCXCursorInvalid(CXCursor_InvalidFile);
4390f4a2713aSLionel Sambuc }
4391f4a2713aSLionel Sambuc
clang_equalCursors(CXCursor X,CXCursor Y)4392f4a2713aSLionel Sambuc unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
4393f4a2713aSLionel Sambuc // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4394f4a2713aSLionel Sambuc // can't set consistently. For example, when visiting a DeclStmt we will set
4395f4a2713aSLionel Sambuc // it but we don't set it on the result of clang_getCursorDefinition for
4396f4a2713aSLionel Sambuc // a reference of the same declaration.
4397f4a2713aSLionel Sambuc // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4398f4a2713aSLionel Sambuc // when visiting a DeclStmt currently, the AST should be enhanced to be able
4399f4a2713aSLionel Sambuc // to provide that kind of info.
4400f4a2713aSLionel Sambuc if (clang_isDeclaration(X.kind))
4401*0a6a1f1dSLionel Sambuc X.data[1] = nullptr;
4402f4a2713aSLionel Sambuc if (clang_isDeclaration(Y.kind))
4403*0a6a1f1dSLionel Sambuc Y.data[1] = nullptr;
4404f4a2713aSLionel Sambuc
4405f4a2713aSLionel Sambuc return X == Y;
4406f4a2713aSLionel Sambuc }
4407f4a2713aSLionel Sambuc
clang_hashCursor(CXCursor C)4408f4a2713aSLionel Sambuc unsigned clang_hashCursor(CXCursor C) {
4409f4a2713aSLionel Sambuc unsigned Index = 0;
4410f4a2713aSLionel Sambuc if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4411f4a2713aSLionel Sambuc Index = 1;
4412f4a2713aSLionel Sambuc
4413f4a2713aSLionel Sambuc return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
4414f4a2713aSLionel Sambuc std::make_pair(C.kind, C.data[Index]));
4415f4a2713aSLionel Sambuc }
4416f4a2713aSLionel Sambuc
clang_isInvalid(enum CXCursorKind K)4417f4a2713aSLionel Sambuc unsigned clang_isInvalid(enum CXCursorKind K) {
4418f4a2713aSLionel Sambuc return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4419f4a2713aSLionel Sambuc }
4420f4a2713aSLionel Sambuc
clang_isDeclaration(enum CXCursorKind K)4421f4a2713aSLionel Sambuc unsigned clang_isDeclaration(enum CXCursorKind K) {
4422f4a2713aSLionel Sambuc return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4423f4a2713aSLionel Sambuc (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4424f4a2713aSLionel Sambuc }
4425f4a2713aSLionel Sambuc
clang_isReference(enum CXCursorKind K)4426f4a2713aSLionel Sambuc unsigned clang_isReference(enum CXCursorKind K) {
4427f4a2713aSLionel Sambuc return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4428f4a2713aSLionel Sambuc }
4429f4a2713aSLionel Sambuc
clang_isExpression(enum CXCursorKind K)4430f4a2713aSLionel Sambuc unsigned clang_isExpression(enum CXCursorKind K) {
4431f4a2713aSLionel Sambuc return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4432f4a2713aSLionel Sambuc }
4433f4a2713aSLionel Sambuc
clang_isStatement(enum CXCursorKind K)4434f4a2713aSLionel Sambuc unsigned clang_isStatement(enum CXCursorKind K) {
4435f4a2713aSLionel Sambuc return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4436f4a2713aSLionel Sambuc }
4437f4a2713aSLionel Sambuc
clang_isAttribute(enum CXCursorKind K)4438f4a2713aSLionel Sambuc unsigned clang_isAttribute(enum CXCursorKind K) {
4439f4a2713aSLionel Sambuc return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4440f4a2713aSLionel Sambuc }
4441f4a2713aSLionel Sambuc
clang_isTranslationUnit(enum CXCursorKind K)4442f4a2713aSLionel Sambuc unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4443f4a2713aSLionel Sambuc return K == CXCursor_TranslationUnit;
4444f4a2713aSLionel Sambuc }
4445f4a2713aSLionel Sambuc
clang_isPreprocessing(enum CXCursorKind K)4446f4a2713aSLionel Sambuc unsigned clang_isPreprocessing(enum CXCursorKind K) {
4447f4a2713aSLionel Sambuc return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4448f4a2713aSLionel Sambuc }
4449f4a2713aSLionel Sambuc
clang_isUnexposed(enum CXCursorKind K)4450f4a2713aSLionel Sambuc unsigned clang_isUnexposed(enum CXCursorKind K) {
4451f4a2713aSLionel Sambuc switch (K) {
4452f4a2713aSLionel Sambuc case CXCursor_UnexposedDecl:
4453f4a2713aSLionel Sambuc case CXCursor_UnexposedExpr:
4454f4a2713aSLionel Sambuc case CXCursor_UnexposedStmt:
4455f4a2713aSLionel Sambuc case CXCursor_UnexposedAttr:
4456f4a2713aSLionel Sambuc return true;
4457f4a2713aSLionel Sambuc default:
4458f4a2713aSLionel Sambuc return false;
4459f4a2713aSLionel Sambuc }
4460f4a2713aSLionel Sambuc }
4461f4a2713aSLionel Sambuc
clang_getCursorKind(CXCursor C)4462f4a2713aSLionel Sambuc CXCursorKind clang_getCursorKind(CXCursor C) {
4463f4a2713aSLionel Sambuc return C.kind;
4464f4a2713aSLionel Sambuc }
4465f4a2713aSLionel Sambuc
clang_getCursorLocation(CXCursor C)4466f4a2713aSLionel Sambuc CXSourceLocation clang_getCursorLocation(CXCursor C) {
4467f4a2713aSLionel Sambuc if (clang_isReference(C.kind)) {
4468f4a2713aSLionel Sambuc switch (C.kind) {
4469f4a2713aSLionel Sambuc case CXCursor_ObjCSuperClassRef: {
4470f4a2713aSLionel Sambuc std::pair<const ObjCInterfaceDecl *, SourceLocation> P
4471f4a2713aSLionel Sambuc = getCursorObjCSuperClassRef(C);
4472f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4473f4a2713aSLionel Sambuc }
4474f4a2713aSLionel Sambuc
4475f4a2713aSLionel Sambuc case CXCursor_ObjCProtocolRef: {
4476f4a2713aSLionel Sambuc std::pair<const ObjCProtocolDecl *, SourceLocation> P
4477f4a2713aSLionel Sambuc = getCursorObjCProtocolRef(C);
4478f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4479f4a2713aSLionel Sambuc }
4480f4a2713aSLionel Sambuc
4481f4a2713aSLionel Sambuc case CXCursor_ObjCClassRef: {
4482f4a2713aSLionel Sambuc std::pair<const ObjCInterfaceDecl *, SourceLocation> P
4483f4a2713aSLionel Sambuc = getCursorObjCClassRef(C);
4484f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4485f4a2713aSLionel Sambuc }
4486f4a2713aSLionel Sambuc
4487f4a2713aSLionel Sambuc case CXCursor_TypeRef: {
4488f4a2713aSLionel Sambuc std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
4489f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4490f4a2713aSLionel Sambuc }
4491f4a2713aSLionel Sambuc
4492f4a2713aSLionel Sambuc case CXCursor_TemplateRef: {
4493f4a2713aSLionel Sambuc std::pair<const TemplateDecl *, SourceLocation> P =
4494f4a2713aSLionel Sambuc getCursorTemplateRef(C);
4495f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4496f4a2713aSLionel Sambuc }
4497f4a2713aSLionel Sambuc
4498f4a2713aSLionel Sambuc case CXCursor_NamespaceRef: {
4499f4a2713aSLionel Sambuc std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
4500f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4501f4a2713aSLionel Sambuc }
4502f4a2713aSLionel Sambuc
4503f4a2713aSLionel Sambuc case CXCursor_MemberRef: {
4504f4a2713aSLionel Sambuc std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
4505f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4506f4a2713aSLionel Sambuc }
4507f4a2713aSLionel Sambuc
4508f4a2713aSLionel Sambuc case CXCursor_VariableRef: {
4509f4a2713aSLionel Sambuc std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
4510f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4511f4a2713aSLionel Sambuc }
4512f4a2713aSLionel Sambuc
4513f4a2713aSLionel Sambuc case CXCursor_CXXBaseSpecifier: {
4514f4a2713aSLionel Sambuc const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
4515f4a2713aSLionel Sambuc if (!BaseSpec)
4516f4a2713aSLionel Sambuc return clang_getNullLocation();
4517f4a2713aSLionel Sambuc
4518f4a2713aSLionel Sambuc if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4519f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C),
4520f4a2713aSLionel Sambuc TSInfo->getTypeLoc().getBeginLoc());
4521f4a2713aSLionel Sambuc
4522f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C),
4523f4a2713aSLionel Sambuc BaseSpec->getLocStart());
4524f4a2713aSLionel Sambuc }
4525f4a2713aSLionel Sambuc
4526f4a2713aSLionel Sambuc case CXCursor_LabelRef: {
4527f4a2713aSLionel Sambuc std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
4528f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4529f4a2713aSLionel Sambuc }
4530f4a2713aSLionel Sambuc
4531f4a2713aSLionel Sambuc case CXCursor_OverloadedDeclRef:
4532f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C),
4533f4a2713aSLionel Sambuc getCursorOverloadedDeclRef(C).second);
4534f4a2713aSLionel Sambuc
4535f4a2713aSLionel Sambuc default:
4536f4a2713aSLionel Sambuc // FIXME: Need a way to enumerate all non-reference cases.
4537f4a2713aSLionel Sambuc llvm_unreachable("Missed a reference kind");
4538f4a2713aSLionel Sambuc }
4539f4a2713aSLionel Sambuc }
4540f4a2713aSLionel Sambuc
4541f4a2713aSLionel Sambuc if (clang_isExpression(C.kind))
4542f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C),
4543f4a2713aSLionel Sambuc getLocationFromExpr(getCursorExpr(C)));
4544f4a2713aSLionel Sambuc
4545f4a2713aSLionel Sambuc if (clang_isStatement(C.kind))
4546f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C),
4547f4a2713aSLionel Sambuc getCursorStmt(C)->getLocStart());
4548f4a2713aSLionel Sambuc
4549f4a2713aSLionel Sambuc if (C.kind == CXCursor_PreprocessingDirective) {
4550f4a2713aSLionel Sambuc SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4551f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C), L);
4552f4a2713aSLionel Sambuc }
4553f4a2713aSLionel Sambuc
4554f4a2713aSLionel Sambuc if (C.kind == CXCursor_MacroExpansion) {
4555f4a2713aSLionel Sambuc SourceLocation L
4556f4a2713aSLionel Sambuc = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
4557f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C), L);
4558f4a2713aSLionel Sambuc }
4559f4a2713aSLionel Sambuc
4560f4a2713aSLionel Sambuc if (C.kind == CXCursor_MacroDefinition) {
4561f4a2713aSLionel Sambuc SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4562f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C), L);
4563f4a2713aSLionel Sambuc }
4564f4a2713aSLionel Sambuc
4565f4a2713aSLionel Sambuc if (C.kind == CXCursor_InclusionDirective) {
4566f4a2713aSLionel Sambuc SourceLocation L
4567f4a2713aSLionel Sambuc = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4568f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C), L);
4569f4a2713aSLionel Sambuc }
4570f4a2713aSLionel Sambuc
4571f4a2713aSLionel Sambuc if (clang_isAttribute(C.kind)) {
4572f4a2713aSLionel Sambuc SourceLocation L
4573f4a2713aSLionel Sambuc = cxcursor::getCursorAttr(C)->getLocation();
4574f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C), L);
4575f4a2713aSLionel Sambuc }
4576f4a2713aSLionel Sambuc
4577f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
4578f4a2713aSLionel Sambuc return clang_getNullLocation();
4579f4a2713aSLionel Sambuc
4580f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(C);
4581f4a2713aSLionel Sambuc if (!D)
4582f4a2713aSLionel Sambuc return clang_getNullLocation();
4583f4a2713aSLionel Sambuc
4584f4a2713aSLionel Sambuc SourceLocation Loc = D->getLocation();
4585f4a2713aSLionel Sambuc // FIXME: Multiple variables declared in a single declaration
4586f4a2713aSLionel Sambuc // currently lack the information needed to correctly determine their
4587f4a2713aSLionel Sambuc // ranges when accounting for the type-specifier. We use context
4588f4a2713aSLionel Sambuc // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4589f4a2713aSLionel Sambuc // and if so, whether it is the first decl.
4590f4a2713aSLionel Sambuc if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
4591f4a2713aSLionel Sambuc if (!cxcursor::isFirstInDeclGroup(C))
4592f4a2713aSLionel Sambuc Loc = VD->getLocation();
4593f4a2713aSLionel Sambuc }
4594f4a2713aSLionel Sambuc
4595f4a2713aSLionel Sambuc // For ObjC methods, give the start location of the method name.
4596f4a2713aSLionel Sambuc if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
4597f4a2713aSLionel Sambuc Loc = MD->getSelectorStartLoc();
4598f4a2713aSLionel Sambuc
4599f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4600f4a2713aSLionel Sambuc }
4601f4a2713aSLionel Sambuc
4602f4a2713aSLionel Sambuc } // end extern "C"
4603f4a2713aSLionel Sambuc
getCursor(CXTranslationUnit TU,SourceLocation SLoc)4604f4a2713aSLionel Sambuc CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4605f4a2713aSLionel Sambuc assert(TU);
4606f4a2713aSLionel Sambuc
4607f4a2713aSLionel Sambuc // Guard against an invalid SourceLocation, or we may assert in one
4608f4a2713aSLionel Sambuc // of the following calls.
4609f4a2713aSLionel Sambuc if (SLoc.isInvalid())
4610f4a2713aSLionel Sambuc return clang_getNullCursor();
4611f4a2713aSLionel Sambuc
4612f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4613f4a2713aSLionel Sambuc
4614f4a2713aSLionel Sambuc // Translate the given source location to make it point at the beginning of
4615f4a2713aSLionel Sambuc // the token under the cursor.
4616f4a2713aSLionel Sambuc SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4617f4a2713aSLionel Sambuc CXXUnit->getASTContext().getLangOpts());
4618f4a2713aSLionel Sambuc
4619f4a2713aSLionel Sambuc CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4620f4a2713aSLionel Sambuc if (SLoc.isValid()) {
4621f4a2713aSLionel Sambuc GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4622f4a2713aSLionel Sambuc CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4623f4a2713aSLionel Sambuc /*VisitPreprocessorLast=*/true,
4624f4a2713aSLionel Sambuc /*VisitIncludedEntities=*/false,
4625f4a2713aSLionel Sambuc SourceLocation(SLoc));
4626f4a2713aSLionel Sambuc CursorVis.visitFileRegion();
4627f4a2713aSLionel Sambuc }
4628f4a2713aSLionel Sambuc
4629f4a2713aSLionel Sambuc return Result;
4630f4a2713aSLionel Sambuc }
4631f4a2713aSLionel Sambuc
getRawCursorExtent(CXCursor C)4632f4a2713aSLionel Sambuc static SourceRange getRawCursorExtent(CXCursor C) {
4633f4a2713aSLionel Sambuc if (clang_isReference(C.kind)) {
4634f4a2713aSLionel Sambuc switch (C.kind) {
4635f4a2713aSLionel Sambuc case CXCursor_ObjCSuperClassRef:
4636f4a2713aSLionel Sambuc return getCursorObjCSuperClassRef(C).second;
4637f4a2713aSLionel Sambuc
4638f4a2713aSLionel Sambuc case CXCursor_ObjCProtocolRef:
4639f4a2713aSLionel Sambuc return getCursorObjCProtocolRef(C).second;
4640f4a2713aSLionel Sambuc
4641f4a2713aSLionel Sambuc case CXCursor_ObjCClassRef:
4642f4a2713aSLionel Sambuc return getCursorObjCClassRef(C).second;
4643f4a2713aSLionel Sambuc
4644f4a2713aSLionel Sambuc case CXCursor_TypeRef:
4645f4a2713aSLionel Sambuc return getCursorTypeRef(C).second;
4646f4a2713aSLionel Sambuc
4647f4a2713aSLionel Sambuc case CXCursor_TemplateRef:
4648f4a2713aSLionel Sambuc return getCursorTemplateRef(C).second;
4649f4a2713aSLionel Sambuc
4650f4a2713aSLionel Sambuc case CXCursor_NamespaceRef:
4651f4a2713aSLionel Sambuc return getCursorNamespaceRef(C).second;
4652f4a2713aSLionel Sambuc
4653f4a2713aSLionel Sambuc case CXCursor_MemberRef:
4654f4a2713aSLionel Sambuc return getCursorMemberRef(C).second;
4655f4a2713aSLionel Sambuc
4656f4a2713aSLionel Sambuc case CXCursor_CXXBaseSpecifier:
4657f4a2713aSLionel Sambuc return getCursorCXXBaseSpecifier(C)->getSourceRange();
4658f4a2713aSLionel Sambuc
4659f4a2713aSLionel Sambuc case CXCursor_LabelRef:
4660f4a2713aSLionel Sambuc return getCursorLabelRef(C).second;
4661f4a2713aSLionel Sambuc
4662f4a2713aSLionel Sambuc case CXCursor_OverloadedDeclRef:
4663f4a2713aSLionel Sambuc return getCursorOverloadedDeclRef(C).second;
4664f4a2713aSLionel Sambuc
4665f4a2713aSLionel Sambuc case CXCursor_VariableRef:
4666f4a2713aSLionel Sambuc return getCursorVariableRef(C).second;
4667f4a2713aSLionel Sambuc
4668f4a2713aSLionel Sambuc default:
4669f4a2713aSLionel Sambuc // FIXME: Need a way to enumerate all non-reference cases.
4670f4a2713aSLionel Sambuc llvm_unreachable("Missed a reference kind");
4671f4a2713aSLionel Sambuc }
4672f4a2713aSLionel Sambuc }
4673f4a2713aSLionel Sambuc
4674f4a2713aSLionel Sambuc if (clang_isExpression(C.kind))
4675f4a2713aSLionel Sambuc return getCursorExpr(C)->getSourceRange();
4676f4a2713aSLionel Sambuc
4677f4a2713aSLionel Sambuc if (clang_isStatement(C.kind))
4678f4a2713aSLionel Sambuc return getCursorStmt(C)->getSourceRange();
4679f4a2713aSLionel Sambuc
4680f4a2713aSLionel Sambuc if (clang_isAttribute(C.kind))
4681f4a2713aSLionel Sambuc return getCursorAttr(C)->getRange();
4682f4a2713aSLionel Sambuc
4683f4a2713aSLionel Sambuc if (C.kind == CXCursor_PreprocessingDirective)
4684f4a2713aSLionel Sambuc return cxcursor::getCursorPreprocessingDirective(C);
4685f4a2713aSLionel Sambuc
4686f4a2713aSLionel Sambuc if (C.kind == CXCursor_MacroExpansion) {
4687f4a2713aSLionel Sambuc ASTUnit *TU = getCursorASTUnit(C);
4688f4a2713aSLionel Sambuc SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
4689f4a2713aSLionel Sambuc return TU->mapRangeFromPreamble(Range);
4690f4a2713aSLionel Sambuc }
4691f4a2713aSLionel Sambuc
4692f4a2713aSLionel Sambuc if (C.kind == CXCursor_MacroDefinition) {
4693f4a2713aSLionel Sambuc ASTUnit *TU = getCursorASTUnit(C);
4694f4a2713aSLionel Sambuc SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4695f4a2713aSLionel Sambuc return TU->mapRangeFromPreamble(Range);
4696f4a2713aSLionel Sambuc }
4697f4a2713aSLionel Sambuc
4698f4a2713aSLionel Sambuc if (C.kind == CXCursor_InclusionDirective) {
4699f4a2713aSLionel Sambuc ASTUnit *TU = getCursorASTUnit(C);
4700f4a2713aSLionel Sambuc SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4701f4a2713aSLionel Sambuc return TU->mapRangeFromPreamble(Range);
4702f4a2713aSLionel Sambuc }
4703f4a2713aSLionel Sambuc
4704f4a2713aSLionel Sambuc if (C.kind == CXCursor_TranslationUnit) {
4705f4a2713aSLionel Sambuc ASTUnit *TU = getCursorASTUnit(C);
4706f4a2713aSLionel Sambuc FileID MainID = TU->getSourceManager().getMainFileID();
4707f4a2713aSLionel Sambuc SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4708f4a2713aSLionel Sambuc SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4709f4a2713aSLionel Sambuc return SourceRange(Start, End);
4710f4a2713aSLionel Sambuc }
4711f4a2713aSLionel Sambuc
4712f4a2713aSLionel Sambuc if (clang_isDeclaration(C.kind)) {
4713f4a2713aSLionel Sambuc const Decl *D = cxcursor::getCursorDecl(C);
4714f4a2713aSLionel Sambuc if (!D)
4715f4a2713aSLionel Sambuc return SourceRange();
4716f4a2713aSLionel Sambuc
4717f4a2713aSLionel Sambuc SourceRange R = D->getSourceRange();
4718f4a2713aSLionel Sambuc // FIXME: Multiple variables declared in a single declaration
4719f4a2713aSLionel Sambuc // currently lack the information needed to correctly determine their
4720f4a2713aSLionel Sambuc // ranges when accounting for the type-specifier. We use context
4721f4a2713aSLionel Sambuc // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4722f4a2713aSLionel Sambuc // and if so, whether it is the first decl.
4723f4a2713aSLionel Sambuc if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
4724f4a2713aSLionel Sambuc if (!cxcursor::isFirstInDeclGroup(C))
4725f4a2713aSLionel Sambuc R.setBegin(VD->getLocation());
4726f4a2713aSLionel Sambuc }
4727f4a2713aSLionel Sambuc return R;
4728f4a2713aSLionel Sambuc }
4729f4a2713aSLionel Sambuc return SourceRange();
4730f4a2713aSLionel Sambuc }
4731f4a2713aSLionel Sambuc
4732f4a2713aSLionel Sambuc /// \brief Retrieves the "raw" cursor extent, which is then extended to include
4733f4a2713aSLionel Sambuc /// the decl-specifier-seq for declarations.
getFullCursorExtent(CXCursor C,SourceManager & SrcMgr)4734f4a2713aSLionel Sambuc static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4735f4a2713aSLionel Sambuc if (clang_isDeclaration(C.kind)) {
4736f4a2713aSLionel Sambuc const Decl *D = cxcursor::getCursorDecl(C);
4737f4a2713aSLionel Sambuc if (!D)
4738f4a2713aSLionel Sambuc return SourceRange();
4739f4a2713aSLionel Sambuc
4740f4a2713aSLionel Sambuc SourceRange R = D->getSourceRange();
4741f4a2713aSLionel Sambuc
4742f4a2713aSLionel Sambuc // Adjust the start of the location for declarations preceded by
4743f4a2713aSLionel Sambuc // declaration specifiers.
4744f4a2713aSLionel Sambuc SourceLocation StartLoc;
4745f4a2713aSLionel Sambuc if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4746f4a2713aSLionel Sambuc if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4747f4a2713aSLionel Sambuc StartLoc = TI->getTypeLoc().getLocStart();
4748f4a2713aSLionel Sambuc } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4749f4a2713aSLionel Sambuc if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4750f4a2713aSLionel Sambuc StartLoc = TI->getTypeLoc().getLocStart();
4751f4a2713aSLionel Sambuc }
4752f4a2713aSLionel Sambuc
4753f4a2713aSLionel Sambuc if (StartLoc.isValid() && R.getBegin().isValid() &&
4754f4a2713aSLionel Sambuc SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4755f4a2713aSLionel Sambuc R.setBegin(StartLoc);
4756f4a2713aSLionel Sambuc
4757f4a2713aSLionel Sambuc // FIXME: Multiple variables declared in a single declaration
4758f4a2713aSLionel Sambuc // currently lack the information needed to correctly determine their
4759f4a2713aSLionel Sambuc // ranges when accounting for the type-specifier. We use context
4760f4a2713aSLionel Sambuc // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4761f4a2713aSLionel Sambuc // and if so, whether it is the first decl.
4762f4a2713aSLionel Sambuc if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
4763f4a2713aSLionel Sambuc if (!cxcursor::isFirstInDeclGroup(C))
4764f4a2713aSLionel Sambuc R.setBegin(VD->getLocation());
4765f4a2713aSLionel Sambuc }
4766f4a2713aSLionel Sambuc
4767f4a2713aSLionel Sambuc return R;
4768f4a2713aSLionel Sambuc }
4769f4a2713aSLionel Sambuc
4770f4a2713aSLionel Sambuc return getRawCursorExtent(C);
4771f4a2713aSLionel Sambuc }
4772f4a2713aSLionel Sambuc
4773f4a2713aSLionel Sambuc extern "C" {
4774f4a2713aSLionel Sambuc
clang_getCursorExtent(CXCursor C)4775f4a2713aSLionel Sambuc CXSourceRange clang_getCursorExtent(CXCursor C) {
4776f4a2713aSLionel Sambuc SourceRange R = getRawCursorExtent(C);
4777f4a2713aSLionel Sambuc if (R.isInvalid())
4778f4a2713aSLionel Sambuc return clang_getNullRange();
4779f4a2713aSLionel Sambuc
4780f4a2713aSLionel Sambuc return cxloc::translateSourceRange(getCursorContext(C), R);
4781f4a2713aSLionel Sambuc }
4782f4a2713aSLionel Sambuc
clang_getCursorReferenced(CXCursor C)4783f4a2713aSLionel Sambuc CXCursor clang_getCursorReferenced(CXCursor C) {
4784f4a2713aSLionel Sambuc if (clang_isInvalid(C.kind))
4785f4a2713aSLionel Sambuc return clang_getNullCursor();
4786f4a2713aSLionel Sambuc
4787f4a2713aSLionel Sambuc CXTranslationUnit tu = getCursorTU(C);
4788f4a2713aSLionel Sambuc if (clang_isDeclaration(C.kind)) {
4789f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(C);
4790f4a2713aSLionel Sambuc if (!D)
4791f4a2713aSLionel Sambuc return clang_getNullCursor();
4792f4a2713aSLionel Sambuc if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
4793f4a2713aSLionel Sambuc return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
4794f4a2713aSLionel Sambuc if (const ObjCPropertyImplDecl *PropImpl =
4795f4a2713aSLionel Sambuc dyn_cast<ObjCPropertyImplDecl>(D))
4796f4a2713aSLionel Sambuc if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4797f4a2713aSLionel Sambuc return MakeCXCursor(Property, tu);
4798f4a2713aSLionel Sambuc
4799f4a2713aSLionel Sambuc return C;
4800f4a2713aSLionel Sambuc }
4801f4a2713aSLionel Sambuc
4802f4a2713aSLionel Sambuc if (clang_isExpression(C.kind)) {
4803f4a2713aSLionel Sambuc const Expr *E = getCursorExpr(C);
4804f4a2713aSLionel Sambuc const Decl *D = getDeclFromExpr(E);
4805f4a2713aSLionel Sambuc if (D) {
4806f4a2713aSLionel Sambuc CXCursor declCursor = MakeCXCursor(D, tu);
4807f4a2713aSLionel Sambuc declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4808f4a2713aSLionel Sambuc declCursor);
4809f4a2713aSLionel Sambuc return declCursor;
4810f4a2713aSLionel Sambuc }
4811f4a2713aSLionel Sambuc
4812f4a2713aSLionel Sambuc if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
4813f4a2713aSLionel Sambuc return MakeCursorOverloadedDeclRef(Ovl, tu);
4814f4a2713aSLionel Sambuc
4815f4a2713aSLionel Sambuc return clang_getNullCursor();
4816f4a2713aSLionel Sambuc }
4817f4a2713aSLionel Sambuc
4818f4a2713aSLionel Sambuc if (clang_isStatement(C.kind)) {
4819f4a2713aSLionel Sambuc const Stmt *S = getCursorStmt(C);
4820f4a2713aSLionel Sambuc if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
4821f4a2713aSLionel Sambuc if (LabelDecl *label = Goto->getLabel())
4822f4a2713aSLionel Sambuc if (LabelStmt *labelS = label->getStmt())
4823f4a2713aSLionel Sambuc return MakeCXCursor(labelS, getCursorDecl(C), tu);
4824f4a2713aSLionel Sambuc
4825f4a2713aSLionel Sambuc return clang_getNullCursor();
4826f4a2713aSLionel Sambuc }
4827f4a2713aSLionel Sambuc
4828f4a2713aSLionel Sambuc if (C.kind == CXCursor_MacroExpansion) {
4829f4a2713aSLionel Sambuc if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
4830f4a2713aSLionel Sambuc return MakeMacroDefinitionCursor(Def, tu);
4831f4a2713aSLionel Sambuc }
4832f4a2713aSLionel Sambuc
4833f4a2713aSLionel Sambuc if (!clang_isReference(C.kind))
4834f4a2713aSLionel Sambuc return clang_getNullCursor();
4835f4a2713aSLionel Sambuc
4836f4a2713aSLionel Sambuc switch (C.kind) {
4837f4a2713aSLionel Sambuc case CXCursor_ObjCSuperClassRef:
4838f4a2713aSLionel Sambuc return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4839f4a2713aSLionel Sambuc
4840f4a2713aSLionel Sambuc case CXCursor_ObjCProtocolRef: {
4841f4a2713aSLionel Sambuc const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4842f4a2713aSLionel Sambuc if (const ObjCProtocolDecl *Def = Prot->getDefinition())
4843f4a2713aSLionel Sambuc return MakeCXCursor(Def, tu);
4844f4a2713aSLionel Sambuc
4845f4a2713aSLionel Sambuc return MakeCXCursor(Prot, tu);
4846f4a2713aSLionel Sambuc }
4847f4a2713aSLionel Sambuc
4848f4a2713aSLionel Sambuc case CXCursor_ObjCClassRef: {
4849f4a2713aSLionel Sambuc const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4850f4a2713aSLionel Sambuc if (const ObjCInterfaceDecl *Def = Class->getDefinition())
4851f4a2713aSLionel Sambuc return MakeCXCursor(Def, tu);
4852f4a2713aSLionel Sambuc
4853f4a2713aSLionel Sambuc return MakeCXCursor(Class, tu);
4854f4a2713aSLionel Sambuc }
4855f4a2713aSLionel Sambuc
4856f4a2713aSLionel Sambuc case CXCursor_TypeRef:
4857f4a2713aSLionel Sambuc return MakeCXCursor(getCursorTypeRef(C).first, tu );
4858f4a2713aSLionel Sambuc
4859f4a2713aSLionel Sambuc case CXCursor_TemplateRef:
4860f4a2713aSLionel Sambuc return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4861f4a2713aSLionel Sambuc
4862f4a2713aSLionel Sambuc case CXCursor_NamespaceRef:
4863f4a2713aSLionel Sambuc return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4864f4a2713aSLionel Sambuc
4865f4a2713aSLionel Sambuc case CXCursor_MemberRef:
4866f4a2713aSLionel Sambuc return MakeCXCursor(getCursorMemberRef(C).first, tu );
4867f4a2713aSLionel Sambuc
4868f4a2713aSLionel Sambuc case CXCursor_CXXBaseSpecifier: {
4869f4a2713aSLionel Sambuc const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
4870f4a2713aSLionel Sambuc return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4871f4a2713aSLionel Sambuc tu ));
4872f4a2713aSLionel Sambuc }
4873f4a2713aSLionel Sambuc
4874f4a2713aSLionel Sambuc case CXCursor_LabelRef:
4875f4a2713aSLionel Sambuc // FIXME: We end up faking the "parent" declaration here because we
4876f4a2713aSLionel Sambuc // don't want to make CXCursor larger.
4877f4a2713aSLionel Sambuc return MakeCXCursor(getCursorLabelRef(C).first,
4878f4a2713aSLionel Sambuc cxtu::getASTUnit(tu)->getASTContext()
4879f4a2713aSLionel Sambuc .getTranslationUnitDecl(),
4880f4a2713aSLionel Sambuc tu);
4881f4a2713aSLionel Sambuc
4882f4a2713aSLionel Sambuc case CXCursor_OverloadedDeclRef:
4883f4a2713aSLionel Sambuc return C;
4884f4a2713aSLionel Sambuc
4885f4a2713aSLionel Sambuc case CXCursor_VariableRef:
4886f4a2713aSLionel Sambuc return MakeCXCursor(getCursorVariableRef(C).first, tu);
4887f4a2713aSLionel Sambuc
4888f4a2713aSLionel Sambuc default:
4889f4a2713aSLionel Sambuc // We would prefer to enumerate all non-reference cursor kinds here.
4890f4a2713aSLionel Sambuc llvm_unreachable("Unhandled reference cursor kind");
4891f4a2713aSLionel Sambuc }
4892f4a2713aSLionel Sambuc }
4893f4a2713aSLionel Sambuc
clang_getCursorDefinition(CXCursor C)4894f4a2713aSLionel Sambuc CXCursor clang_getCursorDefinition(CXCursor C) {
4895f4a2713aSLionel Sambuc if (clang_isInvalid(C.kind))
4896f4a2713aSLionel Sambuc return clang_getNullCursor();
4897f4a2713aSLionel Sambuc
4898f4a2713aSLionel Sambuc CXTranslationUnit TU = getCursorTU(C);
4899f4a2713aSLionel Sambuc
4900f4a2713aSLionel Sambuc bool WasReference = false;
4901f4a2713aSLionel Sambuc if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4902f4a2713aSLionel Sambuc C = clang_getCursorReferenced(C);
4903f4a2713aSLionel Sambuc WasReference = true;
4904f4a2713aSLionel Sambuc }
4905f4a2713aSLionel Sambuc
4906f4a2713aSLionel Sambuc if (C.kind == CXCursor_MacroExpansion)
4907f4a2713aSLionel Sambuc return clang_getCursorReferenced(C);
4908f4a2713aSLionel Sambuc
4909f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
4910f4a2713aSLionel Sambuc return clang_getNullCursor();
4911f4a2713aSLionel Sambuc
4912f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(C);
4913f4a2713aSLionel Sambuc if (!D)
4914f4a2713aSLionel Sambuc return clang_getNullCursor();
4915f4a2713aSLionel Sambuc
4916f4a2713aSLionel Sambuc switch (D->getKind()) {
4917f4a2713aSLionel Sambuc // Declaration kinds that don't really separate the notions of
4918f4a2713aSLionel Sambuc // declaration and definition.
4919f4a2713aSLionel Sambuc case Decl::Namespace:
4920f4a2713aSLionel Sambuc case Decl::Typedef:
4921f4a2713aSLionel Sambuc case Decl::TypeAlias:
4922f4a2713aSLionel Sambuc case Decl::TypeAliasTemplate:
4923f4a2713aSLionel Sambuc case Decl::TemplateTypeParm:
4924f4a2713aSLionel Sambuc case Decl::EnumConstant:
4925f4a2713aSLionel Sambuc case Decl::Field:
4926f4a2713aSLionel Sambuc case Decl::MSProperty:
4927f4a2713aSLionel Sambuc case Decl::IndirectField:
4928f4a2713aSLionel Sambuc case Decl::ObjCIvar:
4929f4a2713aSLionel Sambuc case Decl::ObjCAtDefsField:
4930f4a2713aSLionel Sambuc case Decl::ImplicitParam:
4931f4a2713aSLionel Sambuc case Decl::ParmVar:
4932f4a2713aSLionel Sambuc case Decl::NonTypeTemplateParm:
4933f4a2713aSLionel Sambuc case Decl::TemplateTemplateParm:
4934f4a2713aSLionel Sambuc case Decl::ObjCCategoryImpl:
4935f4a2713aSLionel Sambuc case Decl::ObjCImplementation:
4936f4a2713aSLionel Sambuc case Decl::AccessSpec:
4937f4a2713aSLionel Sambuc case Decl::LinkageSpec:
4938f4a2713aSLionel Sambuc case Decl::ObjCPropertyImpl:
4939f4a2713aSLionel Sambuc case Decl::FileScopeAsm:
4940f4a2713aSLionel Sambuc case Decl::StaticAssert:
4941f4a2713aSLionel Sambuc case Decl::Block:
4942f4a2713aSLionel Sambuc case Decl::Captured:
4943f4a2713aSLionel Sambuc case Decl::Label: // FIXME: Is this right??
4944f4a2713aSLionel Sambuc case Decl::ClassScopeFunctionSpecialization:
4945f4a2713aSLionel Sambuc case Decl::Import:
4946f4a2713aSLionel Sambuc case Decl::OMPThreadPrivate:
4947f4a2713aSLionel Sambuc return C;
4948f4a2713aSLionel Sambuc
4949f4a2713aSLionel Sambuc // Declaration kinds that don't make any sense here, but are
4950f4a2713aSLionel Sambuc // nonetheless harmless.
4951f4a2713aSLionel Sambuc case Decl::Empty:
4952f4a2713aSLionel Sambuc case Decl::TranslationUnit:
4953f4a2713aSLionel Sambuc break;
4954f4a2713aSLionel Sambuc
4955f4a2713aSLionel Sambuc // Declaration kinds for which the definition is not resolvable.
4956f4a2713aSLionel Sambuc case Decl::UnresolvedUsingTypename:
4957f4a2713aSLionel Sambuc case Decl::UnresolvedUsingValue:
4958f4a2713aSLionel Sambuc break;
4959f4a2713aSLionel Sambuc
4960f4a2713aSLionel Sambuc case Decl::UsingDirective:
4961f4a2713aSLionel Sambuc return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4962f4a2713aSLionel Sambuc TU);
4963f4a2713aSLionel Sambuc
4964f4a2713aSLionel Sambuc case Decl::NamespaceAlias:
4965f4a2713aSLionel Sambuc return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4966f4a2713aSLionel Sambuc
4967f4a2713aSLionel Sambuc case Decl::Enum:
4968f4a2713aSLionel Sambuc case Decl::Record:
4969f4a2713aSLionel Sambuc case Decl::CXXRecord:
4970f4a2713aSLionel Sambuc case Decl::ClassTemplateSpecialization:
4971f4a2713aSLionel Sambuc case Decl::ClassTemplatePartialSpecialization:
4972f4a2713aSLionel Sambuc if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4973f4a2713aSLionel Sambuc return MakeCXCursor(Def, TU);
4974f4a2713aSLionel Sambuc return clang_getNullCursor();
4975f4a2713aSLionel Sambuc
4976f4a2713aSLionel Sambuc case Decl::Function:
4977f4a2713aSLionel Sambuc case Decl::CXXMethod:
4978f4a2713aSLionel Sambuc case Decl::CXXConstructor:
4979f4a2713aSLionel Sambuc case Decl::CXXDestructor:
4980f4a2713aSLionel Sambuc case Decl::CXXConversion: {
4981*0a6a1f1dSLionel Sambuc const FunctionDecl *Def = nullptr;
4982f4a2713aSLionel Sambuc if (cast<FunctionDecl>(D)->getBody(Def))
4983f4a2713aSLionel Sambuc return MakeCXCursor(Def, TU);
4984f4a2713aSLionel Sambuc return clang_getNullCursor();
4985f4a2713aSLionel Sambuc }
4986f4a2713aSLionel Sambuc
4987f4a2713aSLionel Sambuc case Decl::Var:
4988f4a2713aSLionel Sambuc case Decl::VarTemplateSpecialization:
4989f4a2713aSLionel Sambuc case Decl::VarTemplatePartialSpecialization: {
4990f4a2713aSLionel Sambuc // Ask the variable if it has a definition.
4991f4a2713aSLionel Sambuc if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
4992f4a2713aSLionel Sambuc return MakeCXCursor(Def, TU);
4993f4a2713aSLionel Sambuc return clang_getNullCursor();
4994f4a2713aSLionel Sambuc }
4995f4a2713aSLionel Sambuc
4996f4a2713aSLionel Sambuc case Decl::FunctionTemplate: {
4997*0a6a1f1dSLionel Sambuc const FunctionDecl *Def = nullptr;
4998f4a2713aSLionel Sambuc if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4999f4a2713aSLionel Sambuc return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5000f4a2713aSLionel Sambuc return clang_getNullCursor();
5001f4a2713aSLionel Sambuc }
5002f4a2713aSLionel Sambuc
5003f4a2713aSLionel Sambuc case Decl::ClassTemplate: {
5004f4a2713aSLionel Sambuc if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5005f4a2713aSLionel Sambuc ->getDefinition())
5006f4a2713aSLionel Sambuc return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5007f4a2713aSLionel Sambuc TU);
5008f4a2713aSLionel Sambuc return clang_getNullCursor();
5009f4a2713aSLionel Sambuc }
5010f4a2713aSLionel Sambuc
5011f4a2713aSLionel Sambuc case Decl::VarTemplate: {
5012f4a2713aSLionel Sambuc if (VarDecl *Def =
5013f4a2713aSLionel Sambuc cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5014f4a2713aSLionel Sambuc return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5015f4a2713aSLionel Sambuc return clang_getNullCursor();
5016f4a2713aSLionel Sambuc }
5017f4a2713aSLionel Sambuc
5018f4a2713aSLionel Sambuc case Decl::Using:
5019f4a2713aSLionel Sambuc return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5020f4a2713aSLionel Sambuc D->getLocation(), TU);
5021f4a2713aSLionel Sambuc
5022f4a2713aSLionel Sambuc case Decl::UsingShadow:
5023f4a2713aSLionel Sambuc return clang_getCursorDefinition(
5024f4a2713aSLionel Sambuc MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5025f4a2713aSLionel Sambuc TU));
5026f4a2713aSLionel Sambuc
5027f4a2713aSLionel Sambuc case Decl::ObjCMethod: {
5028f4a2713aSLionel Sambuc const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
5029f4a2713aSLionel Sambuc if (Method->isThisDeclarationADefinition())
5030f4a2713aSLionel Sambuc return C;
5031f4a2713aSLionel Sambuc
5032f4a2713aSLionel Sambuc // Dig out the method definition in the associated
5033f4a2713aSLionel Sambuc // @implementation, if we have it.
5034f4a2713aSLionel Sambuc // FIXME: The ASTs should make finding the definition easier.
5035f4a2713aSLionel Sambuc if (const ObjCInterfaceDecl *Class
5036f4a2713aSLionel Sambuc = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5037f4a2713aSLionel Sambuc if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5038f4a2713aSLionel Sambuc if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5039f4a2713aSLionel Sambuc Method->isInstanceMethod()))
5040f4a2713aSLionel Sambuc if (Def->isThisDeclarationADefinition())
5041f4a2713aSLionel Sambuc return MakeCXCursor(Def, TU);
5042f4a2713aSLionel Sambuc
5043f4a2713aSLionel Sambuc return clang_getNullCursor();
5044f4a2713aSLionel Sambuc }
5045f4a2713aSLionel Sambuc
5046f4a2713aSLionel Sambuc case Decl::ObjCCategory:
5047f4a2713aSLionel Sambuc if (ObjCCategoryImplDecl *Impl
5048f4a2713aSLionel Sambuc = cast<ObjCCategoryDecl>(D)->getImplementation())
5049f4a2713aSLionel Sambuc return MakeCXCursor(Impl, TU);
5050f4a2713aSLionel Sambuc return clang_getNullCursor();
5051f4a2713aSLionel Sambuc
5052f4a2713aSLionel Sambuc case Decl::ObjCProtocol:
5053f4a2713aSLionel Sambuc if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
5054f4a2713aSLionel Sambuc return MakeCXCursor(Def, TU);
5055f4a2713aSLionel Sambuc return clang_getNullCursor();
5056f4a2713aSLionel Sambuc
5057f4a2713aSLionel Sambuc case Decl::ObjCInterface: {
5058f4a2713aSLionel Sambuc // There are two notions of a "definition" for an Objective-C
5059f4a2713aSLionel Sambuc // class: the interface and its implementation. When we resolved a
5060f4a2713aSLionel Sambuc // reference to an Objective-C class, produce the @interface as
5061f4a2713aSLionel Sambuc // the definition; when we were provided with the interface,
5062f4a2713aSLionel Sambuc // produce the @implementation as the definition.
5063f4a2713aSLionel Sambuc const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
5064f4a2713aSLionel Sambuc if (WasReference) {
5065f4a2713aSLionel Sambuc if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
5066f4a2713aSLionel Sambuc return MakeCXCursor(Def, TU);
5067f4a2713aSLionel Sambuc } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5068f4a2713aSLionel Sambuc return MakeCXCursor(Impl, TU);
5069f4a2713aSLionel Sambuc return clang_getNullCursor();
5070f4a2713aSLionel Sambuc }
5071f4a2713aSLionel Sambuc
5072f4a2713aSLionel Sambuc case Decl::ObjCProperty:
5073f4a2713aSLionel Sambuc // FIXME: We don't really know where to find the
5074f4a2713aSLionel Sambuc // ObjCPropertyImplDecls that implement this property.
5075f4a2713aSLionel Sambuc return clang_getNullCursor();
5076f4a2713aSLionel Sambuc
5077f4a2713aSLionel Sambuc case Decl::ObjCCompatibleAlias:
5078f4a2713aSLionel Sambuc if (const ObjCInterfaceDecl *Class
5079f4a2713aSLionel Sambuc = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
5080f4a2713aSLionel Sambuc if (const ObjCInterfaceDecl *Def = Class->getDefinition())
5081f4a2713aSLionel Sambuc return MakeCXCursor(Def, TU);
5082f4a2713aSLionel Sambuc
5083f4a2713aSLionel Sambuc return clang_getNullCursor();
5084f4a2713aSLionel Sambuc
5085f4a2713aSLionel Sambuc case Decl::Friend:
5086f4a2713aSLionel Sambuc if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5087f4a2713aSLionel Sambuc return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5088f4a2713aSLionel Sambuc return clang_getNullCursor();
5089f4a2713aSLionel Sambuc
5090f4a2713aSLionel Sambuc case Decl::FriendTemplate:
5091f4a2713aSLionel Sambuc if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5092f4a2713aSLionel Sambuc return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5093f4a2713aSLionel Sambuc return clang_getNullCursor();
5094f4a2713aSLionel Sambuc }
5095f4a2713aSLionel Sambuc
5096f4a2713aSLionel Sambuc return clang_getNullCursor();
5097f4a2713aSLionel Sambuc }
5098f4a2713aSLionel Sambuc
clang_isCursorDefinition(CXCursor C)5099f4a2713aSLionel Sambuc unsigned clang_isCursorDefinition(CXCursor C) {
5100f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
5101f4a2713aSLionel Sambuc return 0;
5102f4a2713aSLionel Sambuc
5103f4a2713aSLionel Sambuc return clang_getCursorDefinition(C) == C;
5104f4a2713aSLionel Sambuc }
5105f4a2713aSLionel Sambuc
clang_getCanonicalCursor(CXCursor C)5106f4a2713aSLionel Sambuc CXCursor clang_getCanonicalCursor(CXCursor C) {
5107f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
5108f4a2713aSLionel Sambuc return C;
5109f4a2713aSLionel Sambuc
5110f4a2713aSLionel Sambuc if (const Decl *D = getCursorDecl(C)) {
5111f4a2713aSLionel Sambuc if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
5112f4a2713aSLionel Sambuc if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5113f4a2713aSLionel Sambuc return MakeCXCursor(CatD, getCursorTU(C));
5114f4a2713aSLionel Sambuc
5115f4a2713aSLionel Sambuc if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5116f4a2713aSLionel Sambuc if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
5117f4a2713aSLionel Sambuc return MakeCXCursor(IFD, getCursorTU(C));
5118f4a2713aSLionel Sambuc
5119f4a2713aSLionel Sambuc return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5120f4a2713aSLionel Sambuc }
5121f4a2713aSLionel Sambuc
5122f4a2713aSLionel Sambuc return C;
5123f4a2713aSLionel Sambuc }
5124f4a2713aSLionel Sambuc
clang_Cursor_getObjCSelectorIndex(CXCursor cursor)5125f4a2713aSLionel Sambuc int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5126f4a2713aSLionel Sambuc return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5127f4a2713aSLionel Sambuc }
5128f4a2713aSLionel Sambuc
clang_getNumOverloadedDecls(CXCursor C)5129f4a2713aSLionel Sambuc unsigned clang_getNumOverloadedDecls(CXCursor C) {
5130f4a2713aSLionel Sambuc if (C.kind != CXCursor_OverloadedDeclRef)
5131f4a2713aSLionel Sambuc return 0;
5132f4a2713aSLionel Sambuc
5133f4a2713aSLionel Sambuc OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
5134f4a2713aSLionel Sambuc if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
5135f4a2713aSLionel Sambuc return E->getNumDecls();
5136f4a2713aSLionel Sambuc
5137f4a2713aSLionel Sambuc if (OverloadedTemplateStorage *S
5138f4a2713aSLionel Sambuc = Storage.dyn_cast<OverloadedTemplateStorage*>())
5139f4a2713aSLionel Sambuc return S->size();
5140f4a2713aSLionel Sambuc
5141f4a2713aSLionel Sambuc const Decl *D = Storage.get<const Decl *>();
5142f4a2713aSLionel Sambuc if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
5143f4a2713aSLionel Sambuc return Using->shadow_size();
5144f4a2713aSLionel Sambuc
5145f4a2713aSLionel Sambuc return 0;
5146f4a2713aSLionel Sambuc }
5147f4a2713aSLionel Sambuc
clang_getOverloadedDecl(CXCursor cursor,unsigned index)5148f4a2713aSLionel Sambuc CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5149f4a2713aSLionel Sambuc if (cursor.kind != CXCursor_OverloadedDeclRef)
5150f4a2713aSLionel Sambuc return clang_getNullCursor();
5151f4a2713aSLionel Sambuc
5152f4a2713aSLionel Sambuc if (index >= clang_getNumOverloadedDecls(cursor))
5153f4a2713aSLionel Sambuc return clang_getNullCursor();
5154f4a2713aSLionel Sambuc
5155f4a2713aSLionel Sambuc CXTranslationUnit TU = getCursorTU(cursor);
5156f4a2713aSLionel Sambuc OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
5157f4a2713aSLionel Sambuc if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
5158f4a2713aSLionel Sambuc return MakeCXCursor(E->decls_begin()[index], TU);
5159f4a2713aSLionel Sambuc
5160f4a2713aSLionel Sambuc if (OverloadedTemplateStorage *S
5161f4a2713aSLionel Sambuc = Storage.dyn_cast<OverloadedTemplateStorage*>())
5162f4a2713aSLionel Sambuc return MakeCXCursor(S->begin()[index], TU);
5163f4a2713aSLionel Sambuc
5164f4a2713aSLionel Sambuc const Decl *D = Storage.get<const Decl *>();
5165f4a2713aSLionel Sambuc if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
5166f4a2713aSLionel Sambuc // FIXME: This is, unfortunately, linear time.
5167f4a2713aSLionel Sambuc UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5168f4a2713aSLionel Sambuc std::advance(Pos, index);
5169f4a2713aSLionel Sambuc return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5170f4a2713aSLionel Sambuc }
5171f4a2713aSLionel Sambuc
5172f4a2713aSLionel Sambuc return clang_getNullCursor();
5173f4a2713aSLionel Sambuc }
5174f4a2713aSLionel Sambuc
clang_getDefinitionSpellingAndExtent(CXCursor C,const char ** startBuf,const char ** endBuf,unsigned * startLine,unsigned * startColumn,unsigned * endLine,unsigned * endColumn)5175f4a2713aSLionel Sambuc void clang_getDefinitionSpellingAndExtent(CXCursor C,
5176f4a2713aSLionel Sambuc const char **startBuf,
5177f4a2713aSLionel Sambuc const char **endBuf,
5178f4a2713aSLionel Sambuc unsigned *startLine,
5179f4a2713aSLionel Sambuc unsigned *startColumn,
5180f4a2713aSLionel Sambuc unsigned *endLine,
5181f4a2713aSLionel Sambuc unsigned *endColumn) {
5182f4a2713aSLionel Sambuc assert(getCursorDecl(C) && "CXCursor has null decl");
5183f4a2713aSLionel Sambuc const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
5184f4a2713aSLionel Sambuc CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5185f4a2713aSLionel Sambuc
5186f4a2713aSLionel Sambuc SourceManager &SM = FD->getASTContext().getSourceManager();
5187f4a2713aSLionel Sambuc *startBuf = SM.getCharacterData(Body->getLBracLoc());
5188f4a2713aSLionel Sambuc *endBuf = SM.getCharacterData(Body->getRBracLoc());
5189f4a2713aSLionel Sambuc *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5190f4a2713aSLionel Sambuc *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5191f4a2713aSLionel Sambuc *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5192f4a2713aSLionel Sambuc *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5193f4a2713aSLionel Sambuc }
5194f4a2713aSLionel Sambuc
5195f4a2713aSLionel Sambuc
clang_getCursorReferenceNameRange(CXCursor C,unsigned NameFlags,unsigned PieceIndex)5196f4a2713aSLionel Sambuc CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5197f4a2713aSLionel Sambuc unsigned PieceIndex) {
5198f4a2713aSLionel Sambuc RefNamePieces Pieces;
5199f4a2713aSLionel Sambuc
5200f4a2713aSLionel Sambuc switch (C.kind) {
5201f4a2713aSLionel Sambuc case CXCursor_MemberRefExpr:
5202f4a2713aSLionel Sambuc if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
5203f4a2713aSLionel Sambuc Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5204f4a2713aSLionel Sambuc E->getQualifierLoc().getSourceRange());
5205f4a2713aSLionel Sambuc break;
5206f4a2713aSLionel Sambuc
5207f4a2713aSLionel Sambuc case CXCursor_DeclRefExpr:
5208f4a2713aSLionel Sambuc if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
5209f4a2713aSLionel Sambuc Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5210f4a2713aSLionel Sambuc E->getQualifierLoc().getSourceRange(),
5211f4a2713aSLionel Sambuc E->getOptionalExplicitTemplateArgs());
5212f4a2713aSLionel Sambuc break;
5213f4a2713aSLionel Sambuc
5214f4a2713aSLionel Sambuc case CXCursor_CallExpr:
5215f4a2713aSLionel Sambuc if (const CXXOperatorCallExpr *OCE =
5216f4a2713aSLionel Sambuc dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
5217f4a2713aSLionel Sambuc const Expr *Callee = OCE->getCallee();
5218f4a2713aSLionel Sambuc if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
5219f4a2713aSLionel Sambuc Callee = ICE->getSubExpr();
5220f4a2713aSLionel Sambuc
5221f4a2713aSLionel Sambuc if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
5222f4a2713aSLionel Sambuc Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5223f4a2713aSLionel Sambuc DRE->getQualifierLoc().getSourceRange());
5224f4a2713aSLionel Sambuc }
5225f4a2713aSLionel Sambuc break;
5226f4a2713aSLionel Sambuc
5227f4a2713aSLionel Sambuc default:
5228f4a2713aSLionel Sambuc break;
5229f4a2713aSLionel Sambuc }
5230f4a2713aSLionel Sambuc
5231f4a2713aSLionel Sambuc if (Pieces.empty()) {
5232f4a2713aSLionel Sambuc if (PieceIndex == 0)
5233f4a2713aSLionel Sambuc return clang_getCursorExtent(C);
5234f4a2713aSLionel Sambuc } else if (PieceIndex < Pieces.size()) {
5235f4a2713aSLionel Sambuc SourceRange R = Pieces[PieceIndex];
5236f4a2713aSLionel Sambuc if (R.isValid())
5237f4a2713aSLionel Sambuc return cxloc::translateSourceRange(getCursorContext(C), R);
5238f4a2713aSLionel Sambuc }
5239f4a2713aSLionel Sambuc
5240f4a2713aSLionel Sambuc return clang_getNullRange();
5241f4a2713aSLionel Sambuc }
5242f4a2713aSLionel Sambuc
clang_enableStackTraces(void)5243f4a2713aSLionel Sambuc void clang_enableStackTraces(void) {
5244f4a2713aSLionel Sambuc llvm::sys::PrintStackTraceOnErrorSignal();
5245f4a2713aSLionel Sambuc }
5246f4a2713aSLionel Sambuc
clang_executeOnThread(void (* fn)(void *),void * user_data,unsigned stack_size)5247f4a2713aSLionel Sambuc void clang_executeOnThread(void (*fn)(void*), void *user_data,
5248f4a2713aSLionel Sambuc unsigned stack_size) {
5249f4a2713aSLionel Sambuc llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5250f4a2713aSLionel Sambuc }
5251f4a2713aSLionel Sambuc
5252f4a2713aSLionel Sambuc } // end: extern "C"
5253f4a2713aSLionel Sambuc
5254f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
5255f4a2713aSLionel Sambuc // Token-based Operations.
5256f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
5257f4a2713aSLionel Sambuc
5258f4a2713aSLionel Sambuc /* CXToken layout:
5259f4a2713aSLionel Sambuc * int_data[0]: a CXTokenKind
5260f4a2713aSLionel Sambuc * int_data[1]: starting token location
5261f4a2713aSLionel Sambuc * int_data[2]: token length
5262f4a2713aSLionel Sambuc * int_data[3]: reserved
5263f4a2713aSLionel Sambuc * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5264f4a2713aSLionel Sambuc * otherwise unused.
5265f4a2713aSLionel Sambuc */
5266f4a2713aSLionel Sambuc extern "C" {
5267f4a2713aSLionel Sambuc
clang_getTokenKind(CXToken CXTok)5268f4a2713aSLionel Sambuc CXTokenKind clang_getTokenKind(CXToken CXTok) {
5269f4a2713aSLionel Sambuc return static_cast<CXTokenKind>(CXTok.int_data[0]);
5270f4a2713aSLionel Sambuc }
5271f4a2713aSLionel Sambuc
clang_getTokenSpelling(CXTranslationUnit TU,CXToken CXTok)5272f4a2713aSLionel Sambuc CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5273f4a2713aSLionel Sambuc switch (clang_getTokenKind(CXTok)) {
5274f4a2713aSLionel Sambuc case CXToken_Identifier:
5275f4a2713aSLionel Sambuc case CXToken_Keyword:
5276f4a2713aSLionel Sambuc // We know we have an IdentifierInfo*, so use that.
5277f4a2713aSLionel Sambuc return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
5278f4a2713aSLionel Sambuc ->getNameStart());
5279f4a2713aSLionel Sambuc
5280f4a2713aSLionel Sambuc case CXToken_Literal: {
5281f4a2713aSLionel Sambuc // We have stashed the starting pointer in the ptr_data field. Use it.
5282f4a2713aSLionel Sambuc const char *Text = static_cast<const char *>(CXTok.ptr_data);
5283f4a2713aSLionel Sambuc return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
5284f4a2713aSLionel Sambuc }
5285f4a2713aSLionel Sambuc
5286f4a2713aSLionel Sambuc case CXToken_Punctuation:
5287f4a2713aSLionel Sambuc case CXToken_Comment:
5288f4a2713aSLionel Sambuc break;
5289f4a2713aSLionel Sambuc }
5290f4a2713aSLionel Sambuc
5291*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
5292*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
5293*0a6a1f1dSLionel Sambuc return cxstring::createEmpty();
5294*0a6a1f1dSLionel Sambuc }
5295*0a6a1f1dSLionel Sambuc
5296f4a2713aSLionel Sambuc // We have to find the starting buffer pointer the hard way, by
5297f4a2713aSLionel Sambuc // deconstructing the source location.
5298f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5299f4a2713aSLionel Sambuc if (!CXXUnit)
5300f4a2713aSLionel Sambuc return cxstring::createEmpty();
5301f4a2713aSLionel Sambuc
5302f4a2713aSLionel Sambuc SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5303f4a2713aSLionel Sambuc std::pair<FileID, unsigned> LocInfo
5304f4a2713aSLionel Sambuc = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5305f4a2713aSLionel Sambuc bool Invalid = false;
5306f4a2713aSLionel Sambuc StringRef Buffer
5307f4a2713aSLionel Sambuc = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5308f4a2713aSLionel Sambuc if (Invalid)
5309f4a2713aSLionel Sambuc return cxstring::createEmpty();
5310f4a2713aSLionel Sambuc
5311f4a2713aSLionel Sambuc return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
5312f4a2713aSLionel Sambuc }
5313f4a2713aSLionel Sambuc
clang_getTokenLocation(CXTranslationUnit TU,CXToken CXTok)5314f4a2713aSLionel Sambuc CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
5315*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
5316*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
5317*0a6a1f1dSLionel Sambuc return clang_getNullLocation();
5318*0a6a1f1dSLionel Sambuc }
5319*0a6a1f1dSLionel Sambuc
5320f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5321f4a2713aSLionel Sambuc if (!CXXUnit)
5322f4a2713aSLionel Sambuc return clang_getNullLocation();
5323f4a2713aSLionel Sambuc
5324f4a2713aSLionel Sambuc return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5325f4a2713aSLionel Sambuc SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5326f4a2713aSLionel Sambuc }
5327f4a2713aSLionel Sambuc
clang_getTokenExtent(CXTranslationUnit TU,CXToken CXTok)5328f4a2713aSLionel Sambuc CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
5329*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
5330*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
5331*0a6a1f1dSLionel Sambuc return clang_getNullRange();
5332*0a6a1f1dSLionel Sambuc }
5333*0a6a1f1dSLionel Sambuc
5334f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5335f4a2713aSLionel Sambuc if (!CXXUnit)
5336f4a2713aSLionel Sambuc return clang_getNullRange();
5337f4a2713aSLionel Sambuc
5338f4a2713aSLionel Sambuc return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5339f4a2713aSLionel Sambuc SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5340f4a2713aSLionel Sambuc }
5341f4a2713aSLionel Sambuc
getTokens(ASTUnit * CXXUnit,SourceRange Range,SmallVectorImpl<CXToken> & CXTokens)5342f4a2713aSLionel Sambuc static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5343f4a2713aSLionel Sambuc SmallVectorImpl<CXToken> &CXTokens) {
5344f4a2713aSLionel Sambuc SourceManager &SourceMgr = CXXUnit->getSourceManager();
5345f4a2713aSLionel Sambuc std::pair<FileID, unsigned> BeginLocInfo
5346f4a2713aSLionel Sambuc = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
5347f4a2713aSLionel Sambuc std::pair<FileID, unsigned> EndLocInfo
5348f4a2713aSLionel Sambuc = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
5349f4a2713aSLionel Sambuc
5350f4a2713aSLionel Sambuc // Cannot tokenize across files.
5351f4a2713aSLionel Sambuc if (BeginLocInfo.first != EndLocInfo.first)
5352f4a2713aSLionel Sambuc return;
5353f4a2713aSLionel Sambuc
5354f4a2713aSLionel Sambuc // Create a lexer
5355f4a2713aSLionel Sambuc bool Invalid = false;
5356f4a2713aSLionel Sambuc StringRef Buffer
5357f4a2713aSLionel Sambuc = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5358f4a2713aSLionel Sambuc if (Invalid)
5359f4a2713aSLionel Sambuc return;
5360f4a2713aSLionel Sambuc
5361f4a2713aSLionel Sambuc Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5362f4a2713aSLionel Sambuc CXXUnit->getASTContext().getLangOpts(),
5363f4a2713aSLionel Sambuc Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5364f4a2713aSLionel Sambuc Lex.SetCommentRetentionState(true);
5365f4a2713aSLionel Sambuc
5366f4a2713aSLionel Sambuc // Lex tokens until we hit the end of the range.
5367f4a2713aSLionel Sambuc const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5368f4a2713aSLionel Sambuc Token Tok;
5369f4a2713aSLionel Sambuc bool previousWasAt = false;
5370f4a2713aSLionel Sambuc do {
5371f4a2713aSLionel Sambuc // Lex the next token
5372f4a2713aSLionel Sambuc Lex.LexFromRawLexer(Tok);
5373f4a2713aSLionel Sambuc if (Tok.is(tok::eof))
5374f4a2713aSLionel Sambuc break;
5375f4a2713aSLionel Sambuc
5376f4a2713aSLionel Sambuc // Initialize the CXToken.
5377f4a2713aSLionel Sambuc CXToken CXTok;
5378f4a2713aSLionel Sambuc
5379f4a2713aSLionel Sambuc // - Common fields
5380f4a2713aSLionel Sambuc CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5381f4a2713aSLionel Sambuc CXTok.int_data[2] = Tok.getLength();
5382f4a2713aSLionel Sambuc CXTok.int_data[3] = 0;
5383f4a2713aSLionel Sambuc
5384f4a2713aSLionel Sambuc // - Kind-specific fields
5385f4a2713aSLionel Sambuc if (Tok.isLiteral()) {
5386f4a2713aSLionel Sambuc CXTok.int_data[0] = CXToken_Literal;
5387f4a2713aSLionel Sambuc CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
5388f4a2713aSLionel Sambuc } else if (Tok.is(tok::raw_identifier)) {
5389f4a2713aSLionel Sambuc // Lookup the identifier to determine whether we have a keyword.
5390f4a2713aSLionel Sambuc IdentifierInfo *II
5391f4a2713aSLionel Sambuc = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5392f4a2713aSLionel Sambuc
5393f4a2713aSLionel Sambuc if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5394f4a2713aSLionel Sambuc CXTok.int_data[0] = CXToken_Keyword;
5395f4a2713aSLionel Sambuc }
5396f4a2713aSLionel Sambuc else {
5397f4a2713aSLionel Sambuc CXTok.int_data[0] = Tok.is(tok::identifier)
5398f4a2713aSLionel Sambuc ? CXToken_Identifier
5399f4a2713aSLionel Sambuc : CXToken_Keyword;
5400f4a2713aSLionel Sambuc }
5401f4a2713aSLionel Sambuc CXTok.ptr_data = II;
5402f4a2713aSLionel Sambuc } else if (Tok.is(tok::comment)) {
5403f4a2713aSLionel Sambuc CXTok.int_data[0] = CXToken_Comment;
5404*0a6a1f1dSLionel Sambuc CXTok.ptr_data = nullptr;
5405f4a2713aSLionel Sambuc } else {
5406f4a2713aSLionel Sambuc CXTok.int_data[0] = CXToken_Punctuation;
5407*0a6a1f1dSLionel Sambuc CXTok.ptr_data = nullptr;
5408f4a2713aSLionel Sambuc }
5409f4a2713aSLionel Sambuc CXTokens.push_back(CXTok);
5410f4a2713aSLionel Sambuc previousWasAt = Tok.is(tok::at);
5411f4a2713aSLionel Sambuc } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5412f4a2713aSLionel Sambuc }
5413f4a2713aSLionel Sambuc
clang_tokenize(CXTranslationUnit TU,CXSourceRange Range,CXToken ** Tokens,unsigned * NumTokens)5414f4a2713aSLionel Sambuc void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5415f4a2713aSLionel Sambuc CXToken **Tokens, unsigned *NumTokens) {
5416f4a2713aSLionel Sambuc LOG_FUNC_SECTION {
5417f4a2713aSLionel Sambuc *Log << TU << ' ' << Range;
5418f4a2713aSLionel Sambuc }
5419f4a2713aSLionel Sambuc
5420f4a2713aSLionel Sambuc if (Tokens)
5421*0a6a1f1dSLionel Sambuc *Tokens = nullptr;
5422f4a2713aSLionel Sambuc if (NumTokens)
5423f4a2713aSLionel Sambuc *NumTokens = 0;
5424f4a2713aSLionel Sambuc
5425*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
5426*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
5427f4a2713aSLionel Sambuc return;
5428*0a6a1f1dSLionel Sambuc }
5429f4a2713aSLionel Sambuc
5430f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5431f4a2713aSLionel Sambuc if (!CXXUnit || !Tokens || !NumTokens)
5432f4a2713aSLionel Sambuc return;
5433f4a2713aSLionel Sambuc
5434f4a2713aSLionel Sambuc ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5435f4a2713aSLionel Sambuc
5436f4a2713aSLionel Sambuc SourceRange R = cxloc::translateCXSourceRange(Range);
5437f4a2713aSLionel Sambuc if (R.isInvalid())
5438f4a2713aSLionel Sambuc return;
5439f4a2713aSLionel Sambuc
5440f4a2713aSLionel Sambuc SmallVector<CXToken, 32> CXTokens;
5441f4a2713aSLionel Sambuc getTokens(CXXUnit, R, CXTokens);
5442f4a2713aSLionel Sambuc
5443f4a2713aSLionel Sambuc if (CXTokens.empty())
5444f4a2713aSLionel Sambuc return;
5445f4a2713aSLionel Sambuc
5446f4a2713aSLionel Sambuc *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5447f4a2713aSLionel Sambuc memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5448f4a2713aSLionel Sambuc *NumTokens = CXTokens.size();
5449f4a2713aSLionel Sambuc }
5450f4a2713aSLionel Sambuc
clang_disposeTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens)5451f4a2713aSLionel Sambuc void clang_disposeTokens(CXTranslationUnit TU,
5452f4a2713aSLionel Sambuc CXToken *Tokens, unsigned NumTokens) {
5453f4a2713aSLionel Sambuc free(Tokens);
5454f4a2713aSLionel Sambuc }
5455f4a2713aSLionel Sambuc
5456f4a2713aSLionel Sambuc } // end: extern "C"
5457f4a2713aSLionel Sambuc
5458f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
5459f4a2713aSLionel Sambuc // Token annotation APIs.
5460f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
5461f4a2713aSLionel Sambuc
5462f4a2713aSLionel Sambuc static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5463f4a2713aSLionel Sambuc CXCursor parent,
5464f4a2713aSLionel Sambuc CXClientData client_data);
5465f4a2713aSLionel Sambuc static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5466f4a2713aSLionel Sambuc CXClientData client_data);
5467f4a2713aSLionel Sambuc
5468f4a2713aSLionel Sambuc namespace {
5469f4a2713aSLionel Sambuc class AnnotateTokensWorker {
5470f4a2713aSLionel Sambuc CXToken *Tokens;
5471f4a2713aSLionel Sambuc CXCursor *Cursors;
5472f4a2713aSLionel Sambuc unsigned NumTokens;
5473f4a2713aSLionel Sambuc unsigned TokIdx;
5474f4a2713aSLionel Sambuc unsigned PreprocessingTokIdx;
5475f4a2713aSLionel Sambuc CursorVisitor AnnotateVis;
5476f4a2713aSLionel Sambuc SourceManager &SrcMgr;
5477f4a2713aSLionel Sambuc bool HasContextSensitiveKeywords;
5478f4a2713aSLionel Sambuc
5479f4a2713aSLionel Sambuc struct PostChildrenInfo {
5480f4a2713aSLionel Sambuc CXCursor Cursor;
5481f4a2713aSLionel Sambuc SourceRange CursorRange;
5482f4a2713aSLionel Sambuc unsigned BeforeReachingCursorIdx;
5483f4a2713aSLionel Sambuc unsigned BeforeChildrenTokenIdx;
5484f4a2713aSLionel Sambuc };
5485f4a2713aSLionel Sambuc SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
5486f4a2713aSLionel Sambuc
getTok(unsigned Idx)5487*0a6a1f1dSLionel Sambuc CXToken &getTok(unsigned Idx) {
5488*0a6a1f1dSLionel Sambuc assert(Idx < NumTokens);
5489*0a6a1f1dSLionel Sambuc return Tokens[Idx];
5490*0a6a1f1dSLionel Sambuc }
getTok(unsigned Idx) const5491*0a6a1f1dSLionel Sambuc const CXToken &getTok(unsigned Idx) const {
5492*0a6a1f1dSLionel Sambuc assert(Idx < NumTokens);
5493*0a6a1f1dSLionel Sambuc return Tokens[Idx];
5494*0a6a1f1dSLionel Sambuc }
MoreTokens() const5495f4a2713aSLionel Sambuc bool MoreTokens() const { return TokIdx < NumTokens; }
NextToken() const5496f4a2713aSLionel Sambuc unsigned NextToken() const { return TokIdx; }
AdvanceToken()5497f4a2713aSLionel Sambuc void AdvanceToken() { ++TokIdx; }
GetTokenLoc(unsigned tokI)5498f4a2713aSLionel Sambuc SourceLocation GetTokenLoc(unsigned tokI) {
5499*0a6a1f1dSLionel Sambuc return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
5500f4a2713aSLionel Sambuc }
isFunctionMacroToken(unsigned tokI) const5501f4a2713aSLionel Sambuc bool isFunctionMacroToken(unsigned tokI) const {
5502*0a6a1f1dSLionel Sambuc return getTok(tokI).int_data[3] != 0;
5503f4a2713aSLionel Sambuc }
getFunctionMacroTokenLoc(unsigned tokI) const5504f4a2713aSLionel Sambuc SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5505*0a6a1f1dSLionel Sambuc return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
5506f4a2713aSLionel Sambuc }
5507f4a2713aSLionel Sambuc
5508f4a2713aSLionel Sambuc void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
5509f4a2713aSLionel Sambuc bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
5510f4a2713aSLionel Sambuc SourceRange);
5511f4a2713aSLionel Sambuc
5512f4a2713aSLionel Sambuc public:
AnnotateTokensWorker(CXToken * tokens,CXCursor * cursors,unsigned numTokens,CXTranslationUnit TU,SourceRange RegionOfInterest)5513f4a2713aSLionel Sambuc AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
5514f4a2713aSLionel Sambuc CXTranslationUnit TU, SourceRange RegionOfInterest)
5515f4a2713aSLionel Sambuc : Tokens(tokens), Cursors(cursors),
5516f4a2713aSLionel Sambuc NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
5517f4a2713aSLionel Sambuc AnnotateVis(TU,
5518f4a2713aSLionel Sambuc AnnotateTokensVisitor, this,
5519f4a2713aSLionel Sambuc /*VisitPreprocessorLast=*/true,
5520f4a2713aSLionel Sambuc /*VisitIncludedEntities=*/false,
5521f4a2713aSLionel Sambuc RegionOfInterest,
5522f4a2713aSLionel Sambuc /*VisitDeclsOnly=*/false,
5523f4a2713aSLionel Sambuc AnnotateTokensPostChildrenVisitor),
5524f4a2713aSLionel Sambuc SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
5525f4a2713aSLionel Sambuc HasContextSensitiveKeywords(false) { }
5526f4a2713aSLionel Sambuc
VisitChildren(CXCursor C)5527f4a2713aSLionel Sambuc void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5528f4a2713aSLionel Sambuc enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5529f4a2713aSLionel Sambuc bool postVisitChildren(CXCursor cursor);
5530f4a2713aSLionel Sambuc void AnnotateTokens();
5531f4a2713aSLionel Sambuc
5532f4a2713aSLionel Sambuc /// \brief Determine whether the annotator saw any cursors that have
5533f4a2713aSLionel Sambuc /// context-sensitive keywords.
hasContextSensitiveKeywords() const5534f4a2713aSLionel Sambuc bool hasContextSensitiveKeywords() const {
5535f4a2713aSLionel Sambuc return HasContextSensitiveKeywords;
5536f4a2713aSLionel Sambuc }
5537f4a2713aSLionel Sambuc
~AnnotateTokensWorker()5538f4a2713aSLionel Sambuc ~AnnotateTokensWorker() {
5539f4a2713aSLionel Sambuc assert(PostChildrenInfos.empty());
5540f4a2713aSLionel Sambuc }
5541f4a2713aSLionel Sambuc };
5542f4a2713aSLionel Sambuc }
5543f4a2713aSLionel Sambuc
AnnotateTokens()5544f4a2713aSLionel Sambuc void AnnotateTokensWorker::AnnotateTokens() {
5545f4a2713aSLionel Sambuc // Walk the AST within the region of interest, annotating tokens
5546f4a2713aSLionel Sambuc // along the way.
5547f4a2713aSLionel Sambuc AnnotateVis.visitFileRegion();
5548f4a2713aSLionel Sambuc }
5549f4a2713aSLionel Sambuc
updateCursorAnnotation(CXCursor & Cursor,const CXCursor & updateC)5550f4a2713aSLionel Sambuc static inline void updateCursorAnnotation(CXCursor &Cursor,
5551f4a2713aSLionel Sambuc const CXCursor &updateC) {
5552f4a2713aSLionel Sambuc if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
5553f4a2713aSLionel Sambuc return;
5554f4a2713aSLionel Sambuc Cursor = updateC;
5555f4a2713aSLionel Sambuc }
5556f4a2713aSLionel Sambuc
5557f4a2713aSLionel Sambuc /// \brief It annotates and advances tokens with a cursor until the comparison
5558f4a2713aSLionel Sambuc //// between the cursor location and the source range is the same as
5559f4a2713aSLionel Sambuc /// \arg compResult.
5560f4a2713aSLionel Sambuc ///
5561f4a2713aSLionel Sambuc /// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5562f4a2713aSLionel Sambuc /// Pass RangeOverlap to annotate tokens inside a range.
annotateAndAdvanceTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)5563f4a2713aSLionel Sambuc void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5564f4a2713aSLionel Sambuc RangeComparisonResult compResult,
5565f4a2713aSLionel Sambuc SourceRange range) {
5566f4a2713aSLionel Sambuc while (MoreTokens()) {
5567f4a2713aSLionel Sambuc const unsigned I = NextToken();
5568f4a2713aSLionel Sambuc if (isFunctionMacroToken(I))
5569f4a2713aSLionel Sambuc if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5570f4a2713aSLionel Sambuc return;
5571f4a2713aSLionel Sambuc
5572f4a2713aSLionel Sambuc SourceLocation TokLoc = GetTokenLoc(I);
5573f4a2713aSLionel Sambuc if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5574f4a2713aSLionel Sambuc updateCursorAnnotation(Cursors[I], updateC);
5575f4a2713aSLionel Sambuc AdvanceToken();
5576f4a2713aSLionel Sambuc continue;
5577f4a2713aSLionel Sambuc }
5578f4a2713aSLionel Sambuc break;
5579f4a2713aSLionel Sambuc }
5580f4a2713aSLionel Sambuc }
5581f4a2713aSLionel Sambuc
5582f4a2713aSLionel Sambuc /// \brief Special annotation handling for macro argument tokens.
5583f4a2713aSLionel Sambuc /// \returns true if it advanced beyond all macro tokens, false otherwise.
annotateAndAdvanceFunctionMacroTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)5584f4a2713aSLionel Sambuc bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
5585f4a2713aSLionel Sambuc CXCursor updateC,
5586f4a2713aSLionel Sambuc RangeComparisonResult compResult,
5587f4a2713aSLionel Sambuc SourceRange range) {
5588f4a2713aSLionel Sambuc assert(MoreTokens());
5589f4a2713aSLionel Sambuc assert(isFunctionMacroToken(NextToken()) &&
5590f4a2713aSLionel Sambuc "Should be called only for macro arg tokens");
5591f4a2713aSLionel Sambuc
5592f4a2713aSLionel Sambuc // This works differently than annotateAndAdvanceTokens; because expanded
5593f4a2713aSLionel Sambuc // macro arguments can have arbitrary translation-unit source order, we do not
5594f4a2713aSLionel Sambuc // advance the token index one by one until a token fails the range test.
5595f4a2713aSLionel Sambuc // We only advance once past all of the macro arg tokens if all of them
5596f4a2713aSLionel Sambuc // pass the range test. If one of them fails we keep the token index pointing
5597f4a2713aSLionel Sambuc // at the start of the macro arg tokens so that the failing token will be
5598f4a2713aSLionel Sambuc // annotated by a subsequent annotation try.
5599f4a2713aSLionel Sambuc
5600f4a2713aSLionel Sambuc bool atLeastOneCompFail = false;
5601f4a2713aSLionel Sambuc
5602f4a2713aSLionel Sambuc unsigned I = NextToken();
5603f4a2713aSLionel Sambuc for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5604f4a2713aSLionel Sambuc SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5605f4a2713aSLionel Sambuc if (TokLoc.isFileID())
5606f4a2713aSLionel Sambuc continue; // not macro arg token, it's parens or comma.
5607f4a2713aSLionel Sambuc if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5608f4a2713aSLionel Sambuc if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5609f4a2713aSLionel Sambuc Cursors[I] = updateC;
5610f4a2713aSLionel Sambuc } else
5611f4a2713aSLionel Sambuc atLeastOneCompFail = true;
5612f4a2713aSLionel Sambuc }
5613f4a2713aSLionel Sambuc
5614f4a2713aSLionel Sambuc if (atLeastOneCompFail)
5615f4a2713aSLionel Sambuc return false;
5616f4a2713aSLionel Sambuc
5617f4a2713aSLionel Sambuc TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5618f4a2713aSLionel Sambuc return true;
5619f4a2713aSLionel Sambuc }
5620f4a2713aSLionel Sambuc
5621f4a2713aSLionel Sambuc enum CXChildVisitResult
Visit(CXCursor cursor,CXCursor parent)5622f4a2713aSLionel Sambuc AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
5623f4a2713aSLionel Sambuc SourceRange cursorRange = getRawCursorExtent(cursor);
5624f4a2713aSLionel Sambuc if (cursorRange.isInvalid())
5625f4a2713aSLionel Sambuc return CXChildVisit_Recurse;
5626f4a2713aSLionel Sambuc
5627f4a2713aSLionel Sambuc if (!HasContextSensitiveKeywords) {
5628f4a2713aSLionel Sambuc // Objective-C properties can have context-sensitive keywords.
5629f4a2713aSLionel Sambuc if (cursor.kind == CXCursor_ObjCPropertyDecl) {
5630f4a2713aSLionel Sambuc if (const ObjCPropertyDecl *Property
5631f4a2713aSLionel Sambuc = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5632f4a2713aSLionel Sambuc HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5633f4a2713aSLionel Sambuc }
5634f4a2713aSLionel Sambuc // Objective-C methods can have context-sensitive keywords.
5635f4a2713aSLionel Sambuc else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5636f4a2713aSLionel Sambuc cursor.kind == CXCursor_ObjCClassMethodDecl) {
5637f4a2713aSLionel Sambuc if (const ObjCMethodDecl *Method
5638f4a2713aSLionel Sambuc = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5639f4a2713aSLionel Sambuc if (Method->getObjCDeclQualifier())
5640f4a2713aSLionel Sambuc HasContextSensitiveKeywords = true;
5641f4a2713aSLionel Sambuc else {
5642*0a6a1f1dSLionel Sambuc for (const auto *P : Method->params()) {
5643*0a6a1f1dSLionel Sambuc if (P->getObjCDeclQualifier()) {
5644f4a2713aSLionel Sambuc HasContextSensitiveKeywords = true;
5645f4a2713aSLionel Sambuc break;
5646f4a2713aSLionel Sambuc }
5647f4a2713aSLionel Sambuc }
5648f4a2713aSLionel Sambuc }
5649f4a2713aSLionel Sambuc }
5650f4a2713aSLionel Sambuc }
5651f4a2713aSLionel Sambuc // C++ methods can have context-sensitive keywords.
5652f4a2713aSLionel Sambuc else if (cursor.kind == CXCursor_CXXMethod) {
5653f4a2713aSLionel Sambuc if (const CXXMethodDecl *Method
5654f4a2713aSLionel Sambuc = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5655f4a2713aSLionel Sambuc if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5656f4a2713aSLionel Sambuc HasContextSensitiveKeywords = true;
5657f4a2713aSLionel Sambuc }
5658f4a2713aSLionel Sambuc }
5659f4a2713aSLionel Sambuc // C++ classes can have context-sensitive keywords.
5660f4a2713aSLionel Sambuc else if (cursor.kind == CXCursor_StructDecl ||
5661f4a2713aSLionel Sambuc cursor.kind == CXCursor_ClassDecl ||
5662f4a2713aSLionel Sambuc cursor.kind == CXCursor_ClassTemplate ||
5663f4a2713aSLionel Sambuc cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
5664f4a2713aSLionel Sambuc if (const Decl *D = getCursorDecl(cursor))
5665f4a2713aSLionel Sambuc if (D->hasAttr<FinalAttr>())
5666f4a2713aSLionel Sambuc HasContextSensitiveKeywords = true;
5667f4a2713aSLionel Sambuc }
5668f4a2713aSLionel Sambuc }
5669f4a2713aSLionel Sambuc
5670f4a2713aSLionel Sambuc // Don't override a property annotation with its getter/setter method.
5671f4a2713aSLionel Sambuc if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5672f4a2713aSLionel Sambuc parent.kind == CXCursor_ObjCPropertyDecl)
5673f4a2713aSLionel Sambuc return CXChildVisit_Continue;
5674f4a2713aSLionel Sambuc
5675f4a2713aSLionel Sambuc if (clang_isPreprocessing(cursor.kind)) {
5676f4a2713aSLionel Sambuc // Items in the preprocessing record are kept separate from items in
5677f4a2713aSLionel Sambuc // declarations, so we keep a separate token index.
5678f4a2713aSLionel Sambuc unsigned SavedTokIdx = TokIdx;
5679f4a2713aSLionel Sambuc TokIdx = PreprocessingTokIdx;
5680f4a2713aSLionel Sambuc
5681f4a2713aSLionel Sambuc // Skip tokens up until we catch up to the beginning of the preprocessing
5682f4a2713aSLionel Sambuc // entry.
5683f4a2713aSLionel Sambuc while (MoreTokens()) {
5684f4a2713aSLionel Sambuc const unsigned I = NextToken();
5685f4a2713aSLionel Sambuc SourceLocation TokLoc = GetTokenLoc(I);
5686f4a2713aSLionel Sambuc switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5687f4a2713aSLionel Sambuc case RangeBefore:
5688f4a2713aSLionel Sambuc AdvanceToken();
5689f4a2713aSLionel Sambuc continue;
5690f4a2713aSLionel Sambuc case RangeAfter:
5691f4a2713aSLionel Sambuc case RangeOverlap:
5692f4a2713aSLionel Sambuc break;
5693f4a2713aSLionel Sambuc }
5694f4a2713aSLionel Sambuc break;
5695f4a2713aSLionel Sambuc }
5696f4a2713aSLionel Sambuc
5697f4a2713aSLionel Sambuc // Look at all of the tokens within this range.
5698f4a2713aSLionel Sambuc while (MoreTokens()) {
5699f4a2713aSLionel Sambuc const unsigned I = NextToken();
5700f4a2713aSLionel Sambuc SourceLocation TokLoc = GetTokenLoc(I);
5701f4a2713aSLionel Sambuc switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5702f4a2713aSLionel Sambuc case RangeBefore:
5703f4a2713aSLionel Sambuc llvm_unreachable("Infeasible");
5704f4a2713aSLionel Sambuc case RangeAfter:
5705f4a2713aSLionel Sambuc break;
5706f4a2713aSLionel Sambuc case RangeOverlap:
5707f4a2713aSLionel Sambuc // For macro expansions, just note where the beginning of the macro
5708f4a2713aSLionel Sambuc // expansion occurs.
5709f4a2713aSLionel Sambuc if (cursor.kind == CXCursor_MacroExpansion) {
5710f4a2713aSLionel Sambuc if (TokLoc == cursorRange.getBegin())
5711f4a2713aSLionel Sambuc Cursors[I] = cursor;
5712f4a2713aSLionel Sambuc AdvanceToken();
5713f4a2713aSLionel Sambuc break;
5714f4a2713aSLionel Sambuc }
5715f4a2713aSLionel Sambuc // We may have already annotated macro names inside macro definitions.
5716f4a2713aSLionel Sambuc if (Cursors[I].kind != CXCursor_MacroExpansion)
5717f4a2713aSLionel Sambuc Cursors[I] = cursor;
5718f4a2713aSLionel Sambuc AdvanceToken();
5719f4a2713aSLionel Sambuc continue;
5720f4a2713aSLionel Sambuc }
5721f4a2713aSLionel Sambuc break;
5722f4a2713aSLionel Sambuc }
5723f4a2713aSLionel Sambuc
5724f4a2713aSLionel Sambuc // Save the preprocessing token index; restore the non-preprocessing
5725f4a2713aSLionel Sambuc // token index.
5726f4a2713aSLionel Sambuc PreprocessingTokIdx = TokIdx;
5727f4a2713aSLionel Sambuc TokIdx = SavedTokIdx;
5728f4a2713aSLionel Sambuc return CXChildVisit_Recurse;
5729f4a2713aSLionel Sambuc }
5730f4a2713aSLionel Sambuc
5731f4a2713aSLionel Sambuc if (cursorRange.isInvalid())
5732f4a2713aSLionel Sambuc return CXChildVisit_Continue;
5733f4a2713aSLionel Sambuc
5734f4a2713aSLionel Sambuc unsigned BeforeReachingCursorIdx = NextToken();
5735f4a2713aSLionel Sambuc const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
5736f4a2713aSLionel Sambuc const enum CXCursorKind K = clang_getCursorKind(parent);
5737f4a2713aSLionel Sambuc const CXCursor updateC =
5738f4a2713aSLionel Sambuc (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5739f4a2713aSLionel Sambuc // Attributes are annotated out-of-order, skip tokens until we reach it.
5740f4a2713aSLionel Sambuc clang_isAttribute(cursor.kind))
5741f4a2713aSLionel Sambuc ? clang_getNullCursor() : parent;
5742f4a2713aSLionel Sambuc
5743f4a2713aSLionel Sambuc annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5744f4a2713aSLionel Sambuc
5745f4a2713aSLionel Sambuc // Avoid having the cursor of an expression "overwrite" the annotation of the
5746f4a2713aSLionel Sambuc // variable declaration that it belongs to.
5747f4a2713aSLionel Sambuc // This can happen for C++ constructor expressions whose range generally
5748f4a2713aSLionel Sambuc // include the variable declaration, e.g.:
5749f4a2713aSLionel Sambuc // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5750*0a6a1f1dSLionel Sambuc if (clang_isExpression(cursorK) && MoreTokens()) {
5751f4a2713aSLionel Sambuc const Expr *E = getCursorExpr(cursor);
5752f4a2713aSLionel Sambuc if (const Decl *D = getCursorParentDecl(cursor)) {
5753f4a2713aSLionel Sambuc const unsigned I = NextToken();
5754f4a2713aSLionel Sambuc if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5755f4a2713aSLionel Sambuc E->getLocStart() == D->getLocation() &&
5756f4a2713aSLionel Sambuc E->getLocStart() == GetTokenLoc(I)) {
5757f4a2713aSLionel Sambuc updateCursorAnnotation(Cursors[I], updateC);
5758f4a2713aSLionel Sambuc AdvanceToken();
5759f4a2713aSLionel Sambuc }
5760f4a2713aSLionel Sambuc }
5761f4a2713aSLionel Sambuc }
5762f4a2713aSLionel Sambuc
5763f4a2713aSLionel Sambuc // Before recursing into the children keep some state that we are going
5764f4a2713aSLionel Sambuc // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5765f4a2713aSLionel Sambuc // extra work after the child nodes are visited.
5766f4a2713aSLionel Sambuc // Note that we don't call VisitChildren here to avoid traversing statements
5767f4a2713aSLionel Sambuc // code-recursively which can blow the stack.
5768f4a2713aSLionel Sambuc
5769f4a2713aSLionel Sambuc PostChildrenInfo Info;
5770f4a2713aSLionel Sambuc Info.Cursor = cursor;
5771f4a2713aSLionel Sambuc Info.CursorRange = cursorRange;
5772f4a2713aSLionel Sambuc Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
5773f4a2713aSLionel Sambuc Info.BeforeChildrenTokenIdx = NextToken();
5774f4a2713aSLionel Sambuc PostChildrenInfos.push_back(Info);
5775f4a2713aSLionel Sambuc
5776f4a2713aSLionel Sambuc return CXChildVisit_Recurse;
5777f4a2713aSLionel Sambuc }
5778f4a2713aSLionel Sambuc
postVisitChildren(CXCursor cursor)5779f4a2713aSLionel Sambuc bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5780f4a2713aSLionel Sambuc if (PostChildrenInfos.empty())
5781f4a2713aSLionel Sambuc return false;
5782f4a2713aSLionel Sambuc const PostChildrenInfo &Info = PostChildrenInfos.back();
5783f4a2713aSLionel Sambuc if (!clang_equalCursors(Info.Cursor, cursor))
5784f4a2713aSLionel Sambuc return false;
5785f4a2713aSLionel Sambuc
5786f4a2713aSLionel Sambuc const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5787f4a2713aSLionel Sambuc const unsigned AfterChildren = NextToken();
5788f4a2713aSLionel Sambuc SourceRange cursorRange = Info.CursorRange;
5789f4a2713aSLionel Sambuc
5790f4a2713aSLionel Sambuc // Scan the tokens that are at the end of the cursor, but are not captured
5791f4a2713aSLionel Sambuc // but the child cursors.
5792f4a2713aSLionel Sambuc annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5793f4a2713aSLionel Sambuc
5794f4a2713aSLionel Sambuc // Scan the tokens that are at the beginning of the cursor, but are not
5795f4a2713aSLionel Sambuc // capture by the child cursors.
5796f4a2713aSLionel Sambuc for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5797f4a2713aSLionel Sambuc if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5798f4a2713aSLionel Sambuc break;
5799f4a2713aSLionel Sambuc
5800f4a2713aSLionel Sambuc Cursors[I] = cursor;
5801f4a2713aSLionel Sambuc }
5802f4a2713aSLionel Sambuc
5803f4a2713aSLionel Sambuc // Attributes are annotated out-of-order, rewind TokIdx to when we first
5804f4a2713aSLionel Sambuc // encountered the attribute cursor.
5805f4a2713aSLionel Sambuc if (clang_isAttribute(cursor.kind))
5806f4a2713aSLionel Sambuc TokIdx = Info.BeforeReachingCursorIdx;
5807f4a2713aSLionel Sambuc
5808f4a2713aSLionel Sambuc PostChildrenInfos.pop_back();
5809f4a2713aSLionel Sambuc return false;
5810f4a2713aSLionel Sambuc }
5811f4a2713aSLionel Sambuc
AnnotateTokensVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)5812f4a2713aSLionel Sambuc static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5813f4a2713aSLionel Sambuc CXCursor parent,
5814f4a2713aSLionel Sambuc CXClientData client_data) {
5815f4a2713aSLionel Sambuc return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5816f4a2713aSLionel Sambuc }
5817f4a2713aSLionel Sambuc
AnnotateTokensPostChildrenVisitor(CXCursor cursor,CXClientData client_data)5818f4a2713aSLionel Sambuc static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5819f4a2713aSLionel Sambuc CXClientData client_data) {
5820f4a2713aSLionel Sambuc return static_cast<AnnotateTokensWorker*>(client_data)->
5821f4a2713aSLionel Sambuc postVisitChildren(cursor);
5822f4a2713aSLionel Sambuc }
5823f4a2713aSLionel Sambuc
5824f4a2713aSLionel Sambuc namespace {
5825f4a2713aSLionel Sambuc
5826f4a2713aSLionel Sambuc /// \brief Uses the macro expansions in the preprocessing record to find
5827f4a2713aSLionel Sambuc /// and mark tokens that are macro arguments. This info is used by the
5828f4a2713aSLionel Sambuc /// AnnotateTokensWorker.
5829f4a2713aSLionel Sambuc class MarkMacroArgTokensVisitor {
5830f4a2713aSLionel Sambuc SourceManager &SM;
5831f4a2713aSLionel Sambuc CXToken *Tokens;
5832f4a2713aSLionel Sambuc unsigned NumTokens;
5833f4a2713aSLionel Sambuc unsigned CurIdx;
5834f4a2713aSLionel Sambuc
5835f4a2713aSLionel Sambuc public:
MarkMacroArgTokensVisitor(SourceManager & SM,CXToken * tokens,unsigned numTokens)5836f4a2713aSLionel Sambuc MarkMacroArgTokensVisitor(SourceManager &SM,
5837f4a2713aSLionel Sambuc CXToken *tokens, unsigned numTokens)
5838f4a2713aSLionel Sambuc : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5839f4a2713aSLionel Sambuc
visit(CXCursor cursor,CXCursor parent)5840f4a2713aSLionel Sambuc CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5841f4a2713aSLionel Sambuc if (cursor.kind != CXCursor_MacroExpansion)
5842f4a2713aSLionel Sambuc return CXChildVisit_Continue;
5843f4a2713aSLionel Sambuc
5844f4a2713aSLionel Sambuc SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
5845f4a2713aSLionel Sambuc if (macroRange.getBegin() == macroRange.getEnd())
5846f4a2713aSLionel Sambuc return CXChildVisit_Continue; // it's not a function macro.
5847f4a2713aSLionel Sambuc
5848f4a2713aSLionel Sambuc for (; CurIdx < NumTokens; ++CurIdx) {
5849f4a2713aSLionel Sambuc if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5850f4a2713aSLionel Sambuc macroRange.getBegin()))
5851f4a2713aSLionel Sambuc break;
5852f4a2713aSLionel Sambuc }
5853f4a2713aSLionel Sambuc
5854f4a2713aSLionel Sambuc if (CurIdx == NumTokens)
5855f4a2713aSLionel Sambuc return CXChildVisit_Break;
5856f4a2713aSLionel Sambuc
5857f4a2713aSLionel Sambuc for (; CurIdx < NumTokens; ++CurIdx) {
5858f4a2713aSLionel Sambuc SourceLocation tokLoc = getTokenLoc(CurIdx);
5859f4a2713aSLionel Sambuc if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5860f4a2713aSLionel Sambuc break;
5861f4a2713aSLionel Sambuc
5862f4a2713aSLionel Sambuc setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5863f4a2713aSLionel Sambuc }
5864f4a2713aSLionel Sambuc
5865f4a2713aSLionel Sambuc if (CurIdx == NumTokens)
5866f4a2713aSLionel Sambuc return CXChildVisit_Break;
5867f4a2713aSLionel Sambuc
5868f4a2713aSLionel Sambuc return CXChildVisit_Continue;
5869f4a2713aSLionel Sambuc }
5870f4a2713aSLionel Sambuc
5871f4a2713aSLionel Sambuc private:
getTok(unsigned Idx)5872*0a6a1f1dSLionel Sambuc CXToken &getTok(unsigned Idx) {
5873*0a6a1f1dSLionel Sambuc assert(Idx < NumTokens);
5874*0a6a1f1dSLionel Sambuc return Tokens[Idx];
5875*0a6a1f1dSLionel Sambuc }
getTok(unsigned Idx) const5876*0a6a1f1dSLionel Sambuc const CXToken &getTok(unsigned Idx) const {
5877*0a6a1f1dSLionel Sambuc assert(Idx < NumTokens);
5878*0a6a1f1dSLionel Sambuc return Tokens[Idx];
5879*0a6a1f1dSLionel Sambuc }
5880*0a6a1f1dSLionel Sambuc
getTokenLoc(unsigned tokI)5881f4a2713aSLionel Sambuc SourceLocation getTokenLoc(unsigned tokI) {
5882*0a6a1f1dSLionel Sambuc return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
5883f4a2713aSLionel Sambuc }
5884f4a2713aSLionel Sambuc
setFunctionMacroTokenLoc(unsigned tokI,SourceLocation loc)5885f4a2713aSLionel Sambuc void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5886f4a2713aSLionel Sambuc // The third field is reserved and currently not used. Use it here
5887f4a2713aSLionel Sambuc // to mark macro arg expanded tokens with their expanded locations.
5888*0a6a1f1dSLionel Sambuc getTok(tokI).int_data[3] = loc.getRawEncoding();
5889f4a2713aSLionel Sambuc }
5890f4a2713aSLionel Sambuc };
5891f4a2713aSLionel Sambuc
5892f4a2713aSLionel Sambuc } // end anonymous namespace
5893f4a2713aSLionel Sambuc
5894f4a2713aSLionel Sambuc static CXChildVisitResult
MarkMacroArgTokensVisitorDelegate(CXCursor cursor,CXCursor parent,CXClientData client_data)5895f4a2713aSLionel Sambuc MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5896f4a2713aSLionel Sambuc CXClientData client_data) {
5897f4a2713aSLionel Sambuc return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5898f4a2713aSLionel Sambuc parent);
5899f4a2713aSLionel Sambuc }
5900f4a2713aSLionel Sambuc
5901f4a2713aSLionel Sambuc namespace {
5902f4a2713aSLionel Sambuc struct clang_annotateTokens_Data {
5903f4a2713aSLionel Sambuc CXTranslationUnit TU;
5904f4a2713aSLionel Sambuc ASTUnit *CXXUnit;
5905f4a2713aSLionel Sambuc CXToken *Tokens;
5906f4a2713aSLionel Sambuc unsigned NumTokens;
5907f4a2713aSLionel Sambuc CXCursor *Cursors;
5908f4a2713aSLionel Sambuc };
5909f4a2713aSLionel Sambuc }
5910f4a2713aSLionel Sambuc
5911f4a2713aSLionel Sambuc /// \brief Used by \c annotatePreprocessorTokens.
5912f4a2713aSLionel Sambuc /// \returns true if lexing was finished, false otherwise.
lexNext(Lexer & Lex,Token & Tok,unsigned & NextIdx,unsigned NumTokens)5913f4a2713aSLionel Sambuc static bool lexNext(Lexer &Lex, Token &Tok,
5914f4a2713aSLionel Sambuc unsigned &NextIdx, unsigned NumTokens) {
5915f4a2713aSLionel Sambuc if (NextIdx >= NumTokens)
5916f4a2713aSLionel Sambuc return true;
5917f4a2713aSLionel Sambuc
5918f4a2713aSLionel Sambuc ++NextIdx;
5919f4a2713aSLionel Sambuc Lex.LexFromRawLexer(Tok);
5920f4a2713aSLionel Sambuc if (Tok.is(tok::eof))
5921f4a2713aSLionel Sambuc return true;
5922f4a2713aSLionel Sambuc
5923f4a2713aSLionel Sambuc return false;
5924f4a2713aSLionel Sambuc }
5925f4a2713aSLionel Sambuc
annotatePreprocessorTokens(CXTranslationUnit TU,SourceRange RegionOfInterest,CXCursor * Cursors,CXToken * Tokens,unsigned NumTokens)5926f4a2713aSLionel Sambuc static void annotatePreprocessorTokens(CXTranslationUnit TU,
5927f4a2713aSLionel Sambuc SourceRange RegionOfInterest,
5928f4a2713aSLionel Sambuc CXCursor *Cursors,
5929f4a2713aSLionel Sambuc CXToken *Tokens,
5930f4a2713aSLionel Sambuc unsigned NumTokens) {
5931f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5932f4a2713aSLionel Sambuc
5933f4a2713aSLionel Sambuc Preprocessor &PP = CXXUnit->getPreprocessor();
5934f4a2713aSLionel Sambuc SourceManager &SourceMgr = CXXUnit->getSourceManager();
5935f4a2713aSLionel Sambuc std::pair<FileID, unsigned> BeginLocInfo
5936f4a2713aSLionel Sambuc = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
5937f4a2713aSLionel Sambuc std::pair<FileID, unsigned> EndLocInfo
5938f4a2713aSLionel Sambuc = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
5939f4a2713aSLionel Sambuc
5940f4a2713aSLionel Sambuc if (BeginLocInfo.first != EndLocInfo.first)
5941f4a2713aSLionel Sambuc return;
5942f4a2713aSLionel Sambuc
5943f4a2713aSLionel Sambuc StringRef Buffer;
5944f4a2713aSLionel Sambuc bool Invalid = false;
5945f4a2713aSLionel Sambuc Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5946f4a2713aSLionel Sambuc if (Buffer.empty() || Invalid)
5947f4a2713aSLionel Sambuc return;
5948f4a2713aSLionel Sambuc
5949f4a2713aSLionel Sambuc Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5950f4a2713aSLionel Sambuc CXXUnit->getASTContext().getLangOpts(),
5951f4a2713aSLionel Sambuc Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5952f4a2713aSLionel Sambuc Buffer.end());
5953f4a2713aSLionel Sambuc Lex.SetCommentRetentionState(true);
5954f4a2713aSLionel Sambuc
5955f4a2713aSLionel Sambuc unsigned NextIdx = 0;
5956f4a2713aSLionel Sambuc // Lex tokens in raw mode until we hit the end of the range, to avoid
5957f4a2713aSLionel Sambuc // entering #includes or expanding macros.
5958f4a2713aSLionel Sambuc while (true) {
5959f4a2713aSLionel Sambuc Token Tok;
5960f4a2713aSLionel Sambuc if (lexNext(Lex, Tok, NextIdx, NumTokens))
5961f4a2713aSLionel Sambuc break;
5962f4a2713aSLionel Sambuc unsigned TokIdx = NextIdx-1;
5963f4a2713aSLionel Sambuc assert(Tok.getLocation() ==
5964f4a2713aSLionel Sambuc SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
5965f4a2713aSLionel Sambuc
5966f4a2713aSLionel Sambuc reprocess:
5967f4a2713aSLionel Sambuc if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
5968f4a2713aSLionel Sambuc // We have found a preprocessing directive. Annotate the tokens
5969f4a2713aSLionel Sambuc // appropriately.
5970f4a2713aSLionel Sambuc //
5971f4a2713aSLionel Sambuc // FIXME: Some simple tests here could identify macro definitions and
5972f4a2713aSLionel Sambuc // #undefs, to provide specific cursor kinds for those.
5973f4a2713aSLionel Sambuc
5974f4a2713aSLionel Sambuc SourceLocation BeginLoc = Tok.getLocation();
5975f4a2713aSLionel Sambuc if (lexNext(Lex, Tok, NextIdx, NumTokens))
5976f4a2713aSLionel Sambuc break;
5977f4a2713aSLionel Sambuc
5978*0a6a1f1dSLionel Sambuc MacroInfo *MI = nullptr;
5979*0a6a1f1dSLionel Sambuc if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
5980f4a2713aSLionel Sambuc if (lexNext(Lex, Tok, NextIdx, NumTokens))
5981f4a2713aSLionel Sambuc break;
5982f4a2713aSLionel Sambuc
5983f4a2713aSLionel Sambuc if (Tok.is(tok::raw_identifier)) {
5984*0a6a1f1dSLionel Sambuc IdentifierInfo &II =
5985*0a6a1f1dSLionel Sambuc PP.getIdentifierTable().get(Tok.getRawIdentifier());
5986f4a2713aSLionel Sambuc SourceLocation MappedTokLoc =
5987f4a2713aSLionel Sambuc CXXUnit->mapLocationToPreamble(Tok.getLocation());
5988f4a2713aSLionel Sambuc MI = getMacroInfo(II, MappedTokLoc, TU);
5989f4a2713aSLionel Sambuc }
5990f4a2713aSLionel Sambuc }
5991f4a2713aSLionel Sambuc
5992f4a2713aSLionel Sambuc bool finished = false;
5993f4a2713aSLionel Sambuc do {
5994f4a2713aSLionel Sambuc if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5995f4a2713aSLionel Sambuc finished = true;
5996f4a2713aSLionel Sambuc break;
5997f4a2713aSLionel Sambuc }
5998f4a2713aSLionel Sambuc // If we are in a macro definition, check if the token was ever a
5999f4a2713aSLionel Sambuc // macro name and annotate it if that's the case.
6000f4a2713aSLionel Sambuc if (MI) {
6001f4a2713aSLionel Sambuc SourceLocation SaveLoc = Tok.getLocation();
6002f4a2713aSLionel Sambuc Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6003f4a2713aSLionel Sambuc MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6004f4a2713aSLionel Sambuc Tok.setLocation(SaveLoc);
6005f4a2713aSLionel Sambuc if (MacroDef)
6006f4a2713aSLionel Sambuc Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6007f4a2713aSLionel Sambuc Tok.getLocation(), TU);
6008f4a2713aSLionel Sambuc }
6009f4a2713aSLionel Sambuc } while (!Tok.isAtStartOfLine());
6010f4a2713aSLionel Sambuc
6011f4a2713aSLionel Sambuc unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6012f4a2713aSLionel Sambuc assert(TokIdx <= LastIdx);
6013f4a2713aSLionel Sambuc SourceLocation EndLoc =
6014f4a2713aSLionel Sambuc SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6015f4a2713aSLionel Sambuc CXCursor Cursor =
6016f4a2713aSLionel Sambuc MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6017f4a2713aSLionel Sambuc
6018f4a2713aSLionel Sambuc for (; TokIdx <= LastIdx; ++TokIdx)
6019f4a2713aSLionel Sambuc updateCursorAnnotation(Cursors[TokIdx], Cursor);
6020f4a2713aSLionel Sambuc
6021f4a2713aSLionel Sambuc if (finished)
6022f4a2713aSLionel Sambuc break;
6023f4a2713aSLionel Sambuc goto reprocess;
6024f4a2713aSLionel Sambuc }
6025f4a2713aSLionel Sambuc }
6026f4a2713aSLionel Sambuc }
6027f4a2713aSLionel Sambuc
6028f4a2713aSLionel Sambuc // This gets run a separate thread to avoid stack blowout.
clang_annotateTokensImpl(void * UserData)6029f4a2713aSLionel Sambuc static void clang_annotateTokensImpl(void *UserData) {
6030f4a2713aSLionel Sambuc CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6031f4a2713aSLionel Sambuc ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6032f4a2713aSLionel Sambuc CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6033f4a2713aSLionel Sambuc const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6034f4a2713aSLionel Sambuc CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6035f4a2713aSLionel Sambuc
6036f4a2713aSLionel Sambuc CIndexer *CXXIdx = TU->CIdx;
6037f4a2713aSLionel Sambuc if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6038f4a2713aSLionel Sambuc setThreadBackgroundPriority();
6039f4a2713aSLionel Sambuc
6040f4a2713aSLionel Sambuc // Determine the region of interest, which contains all of the tokens.
6041f4a2713aSLionel Sambuc SourceRange RegionOfInterest;
6042f4a2713aSLionel Sambuc RegionOfInterest.setBegin(
6043f4a2713aSLionel Sambuc cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6044f4a2713aSLionel Sambuc RegionOfInterest.setEnd(
6045f4a2713aSLionel Sambuc cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6046f4a2713aSLionel Sambuc Tokens[NumTokens-1])));
6047f4a2713aSLionel Sambuc
6048f4a2713aSLionel Sambuc // Relex the tokens within the source range to look for preprocessing
6049f4a2713aSLionel Sambuc // directives.
6050f4a2713aSLionel Sambuc annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
6051f4a2713aSLionel Sambuc
6052f4a2713aSLionel Sambuc // If begin location points inside a macro argument, set it to the expansion
6053f4a2713aSLionel Sambuc // location so we can have the full context when annotating semantically.
6054f4a2713aSLionel Sambuc {
6055f4a2713aSLionel Sambuc SourceManager &SM = CXXUnit->getSourceManager();
6056f4a2713aSLionel Sambuc SourceLocation Loc =
6057f4a2713aSLionel Sambuc SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6058f4a2713aSLionel Sambuc if (Loc.isMacroID())
6059f4a2713aSLionel Sambuc RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6060f4a2713aSLionel Sambuc }
6061f4a2713aSLionel Sambuc
6062f4a2713aSLionel Sambuc if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6063f4a2713aSLionel Sambuc // Search and mark tokens that are macro argument expansions.
6064f4a2713aSLionel Sambuc MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6065f4a2713aSLionel Sambuc Tokens, NumTokens);
6066f4a2713aSLionel Sambuc CursorVisitor MacroArgMarker(TU,
6067f4a2713aSLionel Sambuc MarkMacroArgTokensVisitorDelegate, &Visitor,
6068f4a2713aSLionel Sambuc /*VisitPreprocessorLast=*/true,
6069f4a2713aSLionel Sambuc /*VisitIncludedEntities=*/false,
6070f4a2713aSLionel Sambuc RegionOfInterest);
6071f4a2713aSLionel Sambuc MacroArgMarker.visitPreprocessedEntitiesInRegion();
6072f4a2713aSLionel Sambuc }
6073f4a2713aSLionel Sambuc
6074f4a2713aSLionel Sambuc // Annotate all of the source locations in the region of interest that map to
6075f4a2713aSLionel Sambuc // a specific cursor.
6076f4a2713aSLionel Sambuc AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
6077f4a2713aSLionel Sambuc
6078f4a2713aSLionel Sambuc // FIXME: We use a ridiculous stack size here because the data-recursion
6079f4a2713aSLionel Sambuc // algorithm uses a large stack frame than the non-data recursive version,
6080f4a2713aSLionel Sambuc // and AnnotationTokensWorker currently transforms the data-recursion
6081f4a2713aSLionel Sambuc // algorithm back into a traditional recursion by explicitly calling
6082f4a2713aSLionel Sambuc // VisitChildren(). We will need to remove this explicit recursive call.
6083f4a2713aSLionel Sambuc W.AnnotateTokens();
6084f4a2713aSLionel Sambuc
6085f4a2713aSLionel Sambuc // If we ran into any entities that involve context-sensitive keywords,
6086f4a2713aSLionel Sambuc // take another pass through the tokens to mark them as such.
6087f4a2713aSLionel Sambuc if (W.hasContextSensitiveKeywords()) {
6088f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumTokens; ++I) {
6089f4a2713aSLionel Sambuc if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6090f4a2713aSLionel Sambuc continue;
6091f4a2713aSLionel Sambuc
6092f4a2713aSLionel Sambuc if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6093f4a2713aSLionel Sambuc IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6094f4a2713aSLionel Sambuc if (const ObjCPropertyDecl *Property
6095f4a2713aSLionel Sambuc = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6096f4a2713aSLionel Sambuc if (Property->getPropertyAttributesAsWritten() != 0 &&
6097f4a2713aSLionel Sambuc llvm::StringSwitch<bool>(II->getName())
6098f4a2713aSLionel Sambuc .Case("readonly", true)
6099f4a2713aSLionel Sambuc .Case("assign", true)
6100f4a2713aSLionel Sambuc .Case("unsafe_unretained", true)
6101f4a2713aSLionel Sambuc .Case("readwrite", true)
6102f4a2713aSLionel Sambuc .Case("retain", true)
6103f4a2713aSLionel Sambuc .Case("copy", true)
6104f4a2713aSLionel Sambuc .Case("nonatomic", true)
6105f4a2713aSLionel Sambuc .Case("atomic", true)
6106f4a2713aSLionel Sambuc .Case("getter", true)
6107f4a2713aSLionel Sambuc .Case("setter", true)
6108f4a2713aSLionel Sambuc .Case("strong", true)
6109f4a2713aSLionel Sambuc .Case("weak", true)
6110f4a2713aSLionel Sambuc .Default(false))
6111f4a2713aSLionel Sambuc Tokens[I].int_data[0] = CXToken_Keyword;
6112f4a2713aSLionel Sambuc }
6113f4a2713aSLionel Sambuc continue;
6114f4a2713aSLionel Sambuc }
6115f4a2713aSLionel Sambuc
6116f4a2713aSLionel Sambuc if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6117f4a2713aSLionel Sambuc Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6118f4a2713aSLionel Sambuc IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6119f4a2713aSLionel Sambuc if (llvm::StringSwitch<bool>(II->getName())
6120f4a2713aSLionel Sambuc .Case("in", true)
6121f4a2713aSLionel Sambuc .Case("out", true)
6122f4a2713aSLionel Sambuc .Case("inout", true)
6123f4a2713aSLionel Sambuc .Case("oneway", true)
6124f4a2713aSLionel Sambuc .Case("bycopy", true)
6125f4a2713aSLionel Sambuc .Case("byref", true)
6126f4a2713aSLionel Sambuc .Default(false))
6127f4a2713aSLionel Sambuc Tokens[I].int_data[0] = CXToken_Keyword;
6128f4a2713aSLionel Sambuc continue;
6129f4a2713aSLionel Sambuc }
6130f4a2713aSLionel Sambuc
6131f4a2713aSLionel Sambuc if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6132f4a2713aSLionel Sambuc Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6133f4a2713aSLionel Sambuc Tokens[I].int_data[0] = CXToken_Keyword;
6134f4a2713aSLionel Sambuc continue;
6135f4a2713aSLionel Sambuc }
6136f4a2713aSLionel Sambuc }
6137f4a2713aSLionel Sambuc }
6138f4a2713aSLionel Sambuc }
6139f4a2713aSLionel Sambuc
6140f4a2713aSLionel Sambuc extern "C" {
6141f4a2713aSLionel Sambuc
clang_annotateTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens,CXCursor * Cursors)6142f4a2713aSLionel Sambuc void clang_annotateTokens(CXTranslationUnit TU,
6143f4a2713aSLionel Sambuc CXToken *Tokens, unsigned NumTokens,
6144f4a2713aSLionel Sambuc CXCursor *Cursors) {
6145*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
6146*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
6147*0a6a1f1dSLionel Sambuc return;
6148*0a6a1f1dSLionel Sambuc }
6149*0a6a1f1dSLionel Sambuc if (NumTokens == 0 || !Tokens || !Cursors) {
6150f4a2713aSLionel Sambuc LOG_FUNC_SECTION { *Log << "<null input>"; }
6151f4a2713aSLionel Sambuc return;
6152f4a2713aSLionel Sambuc }
6153f4a2713aSLionel Sambuc
6154f4a2713aSLionel Sambuc LOG_FUNC_SECTION {
6155f4a2713aSLionel Sambuc *Log << TU << ' ';
6156f4a2713aSLionel Sambuc CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6157f4a2713aSLionel Sambuc CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6158f4a2713aSLionel Sambuc *Log << clang_getRange(bloc, eloc);
6159f4a2713aSLionel Sambuc }
6160f4a2713aSLionel Sambuc
6161f4a2713aSLionel Sambuc // Any token we don't specifically annotate will have a NULL cursor.
6162f4a2713aSLionel Sambuc CXCursor C = clang_getNullCursor();
6163f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumTokens; ++I)
6164f4a2713aSLionel Sambuc Cursors[I] = C;
6165f4a2713aSLionel Sambuc
6166f4a2713aSLionel Sambuc ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6167f4a2713aSLionel Sambuc if (!CXXUnit)
6168f4a2713aSLionel Sambuc return;
6169f4a2713aSLionel Sambuc
6170f4a2713aSLionel Sambuc ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6171f4a2713aSLionel Sambuc
6172f4a2713aSLionel Sambuc clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6173f4a2713aSLionel Sambuc llvm::CrashRecoveryContext CRC;
6174f4a2713aSLionel Sambuc if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6175f4a2713aSLionel Sambuc GetSafetyThreadStackSize() * 2)) {
6176f4a2713aSLionel Sambuc fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6177f4a2713aSLionel Sambuc }
6178f4a2713aSLionel Sambuc }
6179f4a2713aSLionel Sambuc
6180f4a2713aSLionel Sambuc } // end: extern "C"
6181f4a2713aSLionel Sambuc
6182f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6183f4a2713aSLionel Sambuc // Operations for querying linkage of a cursor.
6184f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6185f4a2713aSLionel Sambuc
6186f4a2713aSLionel Sambuc extern "C" {
clang_getCursorLinkage(CXCursor cursor)6187f4a2713aSLionel Sambuc CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6188f4a2713aSLionel Sambuc if (!clang_isDeclaration(cursor.kind))
6189f4a2713aSLionel Sambuc return CXLinkage_Invalid;
6190f4a2713aSLionel Sambuc
6191f4a2713aSLionel Sambuc const Decl *D = cxcursor::getCursorDecl(cursor);
6192f4a2713aSLionel Sambuc if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6193f4a2713aSLionel Sambuc switch (ND->getLinkageInternal()) {
6194f4a2713aSLionel Sambuc case NoLinkage:
6195f4a2713aSLionel Sambuc case VisibleNoLinkage: return CXLinkage_NoLinkage;
6196f4a2713aSLionel Sambuc case InternalLinkage: return CXLinkage_Internal;
6197f4a2713aSLionel Sambuc case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6198f4a2713aSLionel Sambuc case ExternalLinkage: return CXLinkage_External;
6199f4a2713aSLionel Sambuc };
6200f4a2713aSLionel Sambuc
6201f4a2713aSLionel Sambuc return CXLinkage_Invalid;
6202f4a2713aSLionel Sambuc }
6203f4a2713aSLionel Sambuc } // end: extern "C"
6204f4a2713aSLionel Sambuc
6205f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6206f4a2713aSLionel Sambuc // Operations for querying language of a cursor.
6207f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6208f4a2713aSLionel Sambuc
getDeclLanguage(const Decl * D)6209f4a2713aSLionel Sambuc static CXLanguageKind getDeclLanguage(const Decl *D) {
6210f4a2713aSLionel Sambuc if (!D)
6211f4a2713aSLionel Sambuc return CXLanguage_C;
6212f4a2713aSLionel Sambuc
6213f4a2713aSLionel Sambuc switch (D->getKind()) {
6214f4a2713aSLionel Sambuc default:
6215f4a2713aSLionel Sambuc break;
6216f4a2713aSLionel Sambuc case Decl::ImplicitParam:
6217f4a2713aSLionel Sambuc case Decl::ObjCAtDefsField:
6218f4a2713aSLionel Sambuc case Decl::ObjCCategory:
6219f4a2713aSLionel Sambuc case Decl::ObjCCategoryImpl:
6220f4a2713aSLionel Sambuc case Decl::ObjCCompatibleAlias:
6221f4a2713aSLionel Sambuc case Decl::ObjCImplementation:
6222f4a2713aSLionel Sambuc case Decl::ObjCInterface:
6223f4a2713aSLionel Sambuc case Decl::ObjCIvar:
6224f4a2713aSLionel Sambuc case Decl::ObjCMethod:
6225f4a2713aSLionel Sambuc case Decl::ObjCProperty:
6226f4a2713aSLionel Sambuc case Decl::ObjCPropertyImpl:
6227f4a2713aSLionel Sambuc case Decl::ObjCProtocol:
6228f4a2713aSLionel Sambuc return CXLanguage_ObjC;
6229f4a2713aSLionel Sambuc case Decl::CXXConstructor:
6230f4a2713aSLionel Sambuc case Decl::CXXConversion:
6231f4a2713aSLionel Sambuc case Decl::CXXDestructor:
6232f4a2713aSLionel Sambuc case Decl::CXXMethod:
6233f4a2713aSLionel Sambuc case Decl::CXXRecord:
6234f4a2713aSLionel Sambuc case Decl::ClassTemplate:
6235f4a2713aSLionel Sambuc case Decl::ClassTemplatePartialSpecialization:
6236f4a2713aSLionel Sambuc case Decl::ClassTemplateSpecialization:
6237f4a2713aSLionel Sambuc case Decl::Friend:
6238f4a2713aSLionel Sambuc case Decl::FriendTemplate:
6239f4a2713aSLionel Sambuc case Decl::FunctionTemplate:
6240f4a2713aSLionel Sambuc case Decl::LinkageSpec:
6241f4a2713aSLionel Sambuc case Decl::Namespace:
6242f4a2713aSLionel Sambuc case Decl::NamespaceAlias:
6243f4a2713aSLionel Sambuc case Decl::NonTypeTemplateParm:
6244f4a2713aSLionel Sambuc case Decl::StaticAssert:
6245f4a2713aSLionel Sambuc case Decl::TemplateTemplateParm:
6246f4a2713aSLionel Sambuc case Decl::TemplateTypeParm:
6247f4a2713aSLionel Sambuc case Decl::UnresolvedUsingTypename:
6248f4a2713aSLionel Sambuc case Decl::UnresolvedUsingValue:
6249f4a2713aSLionel Sambuc case Decl::Using:
6250f4a2713aSLionel Sambuc case Decl::UsingDirective:
6251f4a2713aSLionel Sambuc case Decl::UsingShadow:
6252f4a2713aSLionel Sambuc return CXLanguage_CPlusPlus;
6253f4a2713aSLionel Sambuc }
6254f4a2713aSLionel Sambuc
6255f4a2713aSLionel Sambuc return CXLanguage_C;
6256f4a2713aSLionel Sambuc }
6257f4a2713aSLionel Sambuc
6258f4a2713aSLionel Sambuc extern "C" {
6259f4a2713aSLionel Sambuc
getCursorAvailabilityForDecl(const Decl * D)6260f4a2713aSLionel Sambuc static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6261f4a2713aSLionel Sambuc if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6262f4a2713aSLionel Sambuc return CXAvailability_Available;
6263f4a2713aSLionel Sambuc
6264f4a2713aSLionel Sambuc switch (D->getAvailability()) {
6265f4a2713aSLionel Sambuc case AR_Available:
6266f4a2713aSLionel Sambuc case AR_NotYetIntroduced:
6267f4a2713aSLionel Sambuc if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6268f4a2713aSLionel Sambuc return getCursorAvailabilityForDecl(
6269f4a2713aSLionel Sambuc cast<Decl>(EnumConst->getDeclContext()));
6270f4a2713aSLionel Sambuc return CXAvailability_Available;
6271f4a2713aSLionel Sambuc
6272f4a2713aSLionel Sambuc case AR_Deprecated:
6273f4a2713aSLionel Sambuc return CXAvailability_Deprecated;
6274f4a2713aSLionel Sambuc
6275f4a2713aSLionel Sambuc case AR_Unavailable:
6276f4a2713aSLionel Sambuc return CXAvailability_NotAvailable;
6277f4a2713aSLionel Sambuc }
6278f4a2713aSLionel Sambuc
6279f4a2713aSLionel Sambuc llvm_unreachable("Unknown availability kind!");
6280f4a2713aSLionel Sambuc }
6281f4a2713aSLionel Sambuc
clang_getCursorAvailability(CXCursor cursor)6282f4a2713aSLionel Sambuc enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6283f4a2713aSLionel Sambuc if (clang_isDeclaration(cursor.kind))
6284f4a2713aSLionel Sambuc if (const Decl *D = cxcursor::getCursorDecl(cursor))
6285f4a2713aSLionel Sambuc return getCursorAvailabilityForDecl(D);
6286f4a2713aSLionel Sambuc
6287f4a2713aSLionel Sambuc return CXAvailability_Available;
6288f4a2713aSLionel Sambuc }
6289f4a2713aSLionel Sambuc
convertVersion(VersionTuple In)6290f4a2713aSLionel Sambuc static CXVersion convertVersion(VersionTuple In) {
6291f4a2713aSLionel Sambuc CXVersion Out = { -1, -1, -1 };
6292f4a2713aSLionel Sambuc if (In.empty())
6293f4a2713aSLionel Sambuc return Out;
6294f4a2713aSLionel Sambuc
6295f4a2713aSLionel Sambuc Out.Major = In.getMajor();
6296f4a2713aSLionel Sambuc
6297f4a2713aSLionel Sambuc Optional<unsigned> Minor = In.getMinor();
6298f4a2713aSLionel Sambuc if (Minor.hasValue())
6299f4a2713aSLionel Sambuc Out.Minor = *Minor;
6300f4a2713aSLionel Sambuc else
6301f4a2713aSLionel Sambuc return Out;
6302f4a2713aSLionel Sambuc
6303f4a2713aSLionel Sambuc Optional<unsigned> Subminor = In.getSubminor();
6304f4a2713aSLionel Sambuc if (Subminor.hasValue())
6305f4a2713aSLionel Sambuc Out.Subminor = *Subminor;
6306f4a2713aSLionel Sambuc
6307f4a2713aSLionel Sambuc return Out;
6308f4a2713aSLionel Sambuc }
6309f4a2713aSLionel Sambuc
getCursorPlatformAvailabilityForDecl(const Decl * D,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,CXPlatformAvailability * availability,int availability_size)6310f4a2713aSLionel Sambuc static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6311f4a2713aSLionel Sambuc int *always_deprecated,
6312f4a2713aSLionel Sambuc CXString *deprecated_message,
6313f4a2713aSLionel Sambuc int *always_unavailable,
6314f4a2713aSLionel Sambuc CXString *unavailable_message,
6315f4a2713aSLionel Sambuc CXPlatformAvailability *availability,
6316f4a2713aSLionel Sambuc int availability_size) {
6317f4a2713aSLionel Sambuc bool HadAvailAttr = false;
6318f4a2713aSLionel Sambuc int N = 0;
6319*0a6a1f1dSLionel Sambuc for (auto A : D->attrs()) {
6320*0a6a1f1dSLionel Sambuc if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
6321f4a2713aSLionel Sambuc HadAvailAttr = true;
6322f4a2713aSLionel Sambuc if (always_deprecated)
6323f4a2713aSLionel Sambuc *always_deprecated = 1;
6324*0a6a1f1dSLionel Sambuc if (deprecated_message) {
6325*0a6a1f1dSLionel Sambuc clang_disposeString(*deprecated_message);
6326f4a2713aSLionel Sambuc *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6327*0a6a1f1dSLionel Sambuc }
6328f4a2713aSLionel Sambuc continue;
6329f4a2713aSLionel Sambuc }
6330f4a2713aSLionel Sambuc
6331*0a6a1f1dSLionel Sambuc if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
6332f4a2713aSLionel Sambuc HadAvailAttr = true;
6333f4a2713aSLionel Sambuc if (always_unavailable)
6334f4a2713aSLionel Sambuc *always_unavailable = 1;
6335f4a2713aSLionel Sambuc if (unavailable_message) {
6336*0a6a1f1dSLionel Sambuc clang_disposeString(*unavailable_message);
6337f4a2713aSLionel Sambuc *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6338f4a2713aSLionel Sambuc }
6339f4a2713aSLionel Sambuc continue;
6340f4a2713aSLionel Sambuc }
6341f4a2713aSLionel Sambuc
6342*0a6a1f1dSLionel Sambuc if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
6343f4a2713aSLionel Sambuc HadAvailAttr = true;
6344f4a2713aSLionel Sambuc if (N < availability_size) {
6345f4a2713aSLionel Sambuc availability[N].Platform
6346f4a2713aSLionel Sambuc = cxstring::createDup(Avail->getPlatform()->getName());
6347f4a2713aSLionel Sambuc availability[N].Introduced = convertVersion(Avail->getIntroduced());
6348f4a2713aSLionel Sambuc availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6349f4a2713aSLionel Sambuc availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6350f4a2713aSLionel Sambuc availability[N].Unavailable = Avail->getUnavailable();
6351f4a2713aSLionel Sambuc availability[N].Message = cxstring::createDup(Avail->getMessage());
6352f4a2713aSLionel Sambuc }
6353f4a2713aSLionel Sambuc ++N;
6354f4a2713aSLionel Sambuc }
6355f4a2713aSLionel Sambuc }
6356f4a2713aSLionel Sambuc
6357f4a2713aSLionel Sambuc if (!HadAvailAttr)
6358f4a2713aSLionel Sambuc if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6359f4a2713aSLionel Sambuc return getCursorPlatformAvailabilityForDecl(
6360f4a2713aSLionel Sambuc cast<Decl>(EnumConst->getDeclContext()),
6361f4a2713aSLionel Sambuc always_deprecated,
6362f4a2713aSLionel Sambuc deprecated_message,
6363f4a2713aSLionel Sambuc always_unavailable,
6364f4a2713aSLionel Sambuc unavailable_message,
6365f4a2713aSLionel Sambuc availability,
6366f4a2713aSLionel Sambuc availability_size);
6367f4a2713aSLionel Sambuc
6368f4a2713aSLionel Sambuc return N;
6369f4a2713aSLionel Sambuc }
6370f4a2713aSLionel Sambuc
clang_getCursorPlatformAvailability(CXCursor cursor,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,CXPlatformAvailability * availability,int availability_size)6371f4a2713aSLionel Sambuc int clang_getCursorPlatformAvailability(CXCursor cursor,
6372f4a2713aSLionel Sambuc int *always_deprecated,
6373f4a2713aSLionel Sambuc CXString *deprecated_message,
6374f4a2713aSLionel Sambuc int *always_unavailable,
6375f4a2713aSLionel Sambuc CXString *unavailable_message,
6376f4a2713aSLionel Sambuc CXPlatformAvailability *availability,
6377f4a2713aSLionel Sambuc int availability_size) {
6378f4a2713aSLionel Sambuc if (always_deprecated)
6379f4a2713aSLionel Sambuc *always_deprecated = 0;
6380f4a2713aSLionel Sambuc if (deprecated_message)
6381f4a2713aSLionel Sambuc *deprecated_message = cxstring::createEmpty();
6382f4a2713aSLionel Sambuc if (always_unavailable)
6383f4a2713aSLionel Sambuc *always_unavailable = 0;
6384f4a2713aSLionel Sambuc if (unavailable_message)
6385f4a2713aSLionel Sambuc *unavailable_message = cxstring::createEmpty();
6386f4a2713aSLionel Sambuc
6387f4a2713aSLionel Sambuc if (!clang_isDeclaration(cursor.kind))
6388f4a2713aSLionel Sambuc return 0;
6389f4a2713aSLionel Sambuc
6390f4a2713aSLionel Sambuc const Decl *D = cxcursor::getCursorDecl(cursor);
6391f4a2713aSLionel Sambuc if (!D)
6392f4a2713aSLionel Sambuc return 0;
6393f4a2713aSLionel Sambuc
6394f4a2713aSLionel Sambuc return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6395f4a2713aSLionel Sambuc deprecated_message,
6396f4a2713aSLionel Sambuc always_unavailable,
6397f4a2713aSLionel Sambuc unavailable_message,
6398f4a2713aSLionel Sambuc availability,
6399f4a2713aSLionel Sambuc availability_size);
6400f4a2713aSLionel Sambuc }
6401f4a2713aSLionel Sambuc
clang_disposeCXPlatformAvailability(CXPlatformAvailability * availability)6402f4a2713aSLionel Sambuc void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6403f4a2713aSLionel Sambuc clang_disposeString(availability->Platform);
6404f4a2713aSLionel Sambuc clang_disposeString(availability->Message);
6405f4a2713aSLionel Sambuc }
6406f4a2713aSLionel Sambuc
clang_getCursorLanguage(CXCursor cursor)6407f4a2713aSLionel Sambuc CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6408f4a2713aSLionel Sambuc if (clang_isDeclaration(cursor.kind))
6409f4a2713aSLionel Sambuc return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6410f4a2713aSLionel Sambuc
6411f4a2713aSLionel Sambuc return CXLanguage_Invalid;
6412f4a2713aSLionel Sambuc }
6413f4a2713aSLionel Sambuc
6414f4a2713aSLionel Sambuc /// \brief If the given cursor is the "templated" declaration
6415f4a2713aSLionel Sambuc /// descibing a class or function template, return the class or
6416f4a2713aSLionel Sambuc /// function template.
maybeGetTemplateCursor(const Decl * D)6417f4a2713aSLionel Sambuc static const Decl *maybeGetTemplateCursor(const Decl *D) {
6418f4a2713aSLionel Sambuc if (!D)
6419*0a6a1f1dSLionel Sambuc return nullptr;
6420f4a2713aSLionel Sambuc
6421f4a2713aSLionel Sambuc if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6422f4a2713aSLionel Sambuc if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6423f4a2713aSLionel Sambuc return FunTmpl;
6424f4a2713aSLionel Sambuc
6425f4a2713aSLionel Sambuc if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
6426f4a2713aSLionel Sambuc if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6427f4a2713aSLionel Sambuc return ClassTmpl;
6428f4a2713aSLionel Sambuc
6429f4a2713aSLionel Sambuc return D;
6430f4a2713aSLionel Sambuc }
6431f4a2713aSLionel Sambuc
6432*0a6a1f1dSLionel Sambuc
clang_Cursor_getStorageClass(CXCursor C)6433*0a6a1f1dSLionel Sambuc enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6434*0a6a1f1dSLionel Sambuc StorageClass sc = SC_None;
6435*0a6a1f1dSLionel Sambuc const Decl *D = getCursorDecl(C);
6436*0a6a1f1dSLionel Sambuc if (D) {
6437*0a6a1f1dSLionel Sambuc if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6438*0a6a1f1dSLionel Sambuc sc = FD->getStorageClass();
6439*0a6a1f1dSLionel Sambuc } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6440*0a6a1f1dSLionel Sambuc sc = VD->getStorageClass();
6441*0a6a1f1dSLionel Sambuc } else {
6442*0a6a1f1dSLionel Sambuc return CX_SC_Invalid;
6443*0a6a1f1dSLionel Sambuc }
6444*0a6a1f1dSLionel Sambuc } else {
6445*0a6a1f1dSLionel Sambuc return CX_SC_Invalid;
6446*0a6a1f1dSLionel Sambuc }
6447*0a6a1f1dSLionel Sambuc switch (sc) {
6448*0a6a1f1dSLionel Sambuc case SC_None:
6449*0a6a1f1dSLionel Sambuc return CX_SC_None;
6450*0a6a1f1dSLionel Sambuc case SC_Extern:
6451*0a6a1f1dSLionel Sambuc return CX_SC_Extern;
6452*0a6a1f1dSLionel Sambuc case SC_Static:
6453*0a6a1f1dSLionel Sambuc return CX_SC_Static;
6454*0a6a1f1dSLionel Sambuc case SC_PrivateExtern:
6455*0a6a1f1dSLionel Sambuc return CX_SC_PrivateExtern;
6456*0a6a1f1dSLionel Sambuc case SC_OpenCLWorkGroupLocal:
6457*0a6a1f1dSLionel Sambuc return CX_SC_OpenCLWorkGroupLocal;
6458*0a6a1f1dSLionel Sambuc case SC_Auto:
6459*0a6a1f1dSLionel Sambuc return CX_SC_Auto;
6460*0a6a1f1dSLionel Sambuc case SC_Register:
6461*0a6a1f1dSLionel Sambuc return CX_SC_Register;
6462*0a6a1f1dSLionel Sambuc }
6463*0a6a1f1dSLionel Sambuc llvm_unreachable("Unhandled storage class!");
6464*0a6a1f1dSLionel Sambuc }
6465*0a6a1f1dSLionel Sambuc
clang_getCursorSemanticParent(CXCursor cursor)6466f4a2713aSLionel Sambuc CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6467f4a2713aSLionel Sambuc if (clang_isDeclaration(cursor.kind)) {
6468f4a2713aSLionel Sambuc if (const Decl *D = getCursorDecl(cursor)) {
6469f4a2713aSLionel Sambuc const DeclContext *DC = D->getDeclContext();
6470f4a2713aSLionel Sambuc if (!DC)
6471f4a2713aSLionel Sambuc return clang_getNullCursor();
6472f4a2713aSLionel Sambuc
6473f4a2713aSLionel Sambuc return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6474f4a2713aSLionel Sambuc getCursorTU(cursor));
6475f4a2713aSLionel Sambuc }
6476f4a2713aSLionel Sambuc }
6477f4a2713aSLionel Sambuc
6478f4a2713aSLionel Sambuc if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
6479f4a2713aSLionel Sambuc if (const Decl *D = getCursorDecl(cursor))
6480f4a2713aSLionel Sambuc return MakeCXCursor(D, getCursorTU(cursor));
6481f4a2713aSLionel Sambuc }
6482f4a2713aSLionel Sambuc
6483f4a2713aSLionel Sambuc return clang_getNullCursor();
6484f4a2713aSLionel Sambuc }
6485f4a2713aSLionel Sambuc
clang_getCursorLexicalParent(CXCursor cursor)6486f4a2713aSLionel Sambuc CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6487f4a2713aSLionel Sambuc if (clang_isDeclaration(cursor.kind)) {
6488f4a2713aSLionel Sambuc if (const Decl *D = getCursorDecl(cursor)) {
6489f4a2713aSLionel Sambuc const DeclContext *DC = D->getLexicalDeclContext();
6490f4a2713aSLionel Sambuc if (!DC)
6491f4a2713aSLionel Sambuc return clang_getNullCursor();
6492f4a2713aSLionel Sambuc
6493f4a2713aSLionel Sambuc return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6494f4a2713aSLionel Sambuc getCursorTU(cursor));
6495f4a2713aSLionel Sambuc }
6496f4a2713aSLionel Sambuc }
6497f4a2713aSLionel Sambuc
6498f4a2713aSLionel Sambuc // FIXME: Note that we can't easily compute the lexical context of a
6499f4a2713aSLionel Sambuc // statement or expression, so we return nothing.
6500f4a2713aSLionel Sambuc return clang_getNullCursor();
6501f4a2713aSLionel Sambuc }
6502f4a2713aSLionel Sambuc
clang_getIncludedFile(CXCursor cursor)6503f4a2713aSLionel Sambuc CXFile clang_getIncludedFile(CXCursor cursor) {
6504f4a2713aSLionel Sambuc if (cursor.kind != CXCursor_InclusionDirective)
6505*0a6a1f1dSLionel Sambuc return nullptr;
6506f4a2713aSLionel Sambuc
6507f4a2713aSLionel Sambuc const InclusionDirective *ID = getCursorInclusionDirective(cursor);
6508f4a2713aSLionel Sambuc return const_cast<FileEntry *>(ID->getFile());
6509f4a2713aSLionel Sambuc }
6510f4a2713aSLionel Sambuc
clang_Cursor_getObjCPropertyAttributes(CXCursor C,unsigned reserved)6511f4a2713aSLionel Sambuc unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6512f4a2713aSLionel Sambuc if (C.kind != CXCursor_ObjCPropertyDecl)
6513f4a2713aSLionel Sambuc return CXObjCPropertyAttr_noattr;
6514f4a2713aSLionel Sambuc
6515f4a2713aSLionel Sambuc unsigned Result = CXObjCPropertyAttr_noattr;
6516f4a2713aSLionel Sambuc const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6517f4a2713aSLionel Sambuc ObjCPropertyDecl::PropertyAttributeKind Attr =
6518f4a2713aSLionel Sambuc PD->getPropertyAttributesAsWritten();
6519f4a2713aSLionel Sambuc
6520f4a2713aSLionel Sambuc #define SET_CXOBJCPROP_ATTR(A) \
6521f4a2713aSLionel Sambuc if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6522f4a2713aSLionel Sambuc Result |= CXObjCPropertyAttr_##A
6523f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(readonly);
6524f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(getter);
6525f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(assign);
6526f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(readwrite);
6527f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(retain);
6528f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(copy);
6529f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(nonatomic);
6530f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(setter);
6531f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(atomic);
6532f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(weak);
6533f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(strong);
6534f4a2713aSLionel Sambuc SET_CXOBJCPROP_ATTR(unsafe_unretained);
6535f4a2713aSLionel Sambuc #undef SET_CXOBJCPROP_ATTR
6536f4a2713aSLionel Sambuc
6537f4a2713aSLionel Sambuc return Result;
6538f4a2713aSLionel Sambuc }
6539f4a2713aSLionel Sambuc
clang_Cursor_getObjCDeclQualifiers(CXCursor C)6540f4a2713aSLionel Sambuc unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6541f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
6542f4a2713aSLionel Sambuc return CXObjCDeclQualifier_None;
6543f4a2713aSLionel Sambuc
6544f4a2713aSLionel Sambuc Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6545f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(C);
6546f4a2713aSLionel Sambuc if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6547f4a2713aSLionel Sambuc QT = MD->getObjCDeclQualifier();
6548f4a2713aSLionel Sambuc else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6549f4a2713aSLionel Sambuc QT = PD->getObjCDeclQualifier();
6550f4a2713aSLionel Sambuc if (QT == Decl::OBJC_TQ_None)
6551f4a2713aSLionel Sambuc return CXObjCDeclQualifier_None;
6552f4a2713aSLionel Sambuc
6553f4a2713aSLionel Sambuc unsigned Result = CXObjCDeclQualifier_None;
6554f4a2713aSLionel Sambuc if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6555f4a2713aSLionel Sambuc if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6556f4a2713aSLionel Sambuc if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6557f4a2713aSLionel Sambuc if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6558f4a2713aSLionel Sambuc if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6559f4a2713aSLionel Sambuc if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6560f4a2713aSLionel Sambuc
6561f4a2713aSLionel Sambuc return Result;
6562f4a2713aSLionel Sambuc }
6563f4a2713aSLionel Sambuc
clang_Cursor_isObjCOptional(CXCursor C)6564f4a2713aSLionel Sambuc unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6565f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
6566f4a2713aSLionel Sambuc return 0;
6567f4a2713aSLionel Sambuc
6568f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(C);
6569f4a2713aSLionel Sambuc if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6570f4a2713aSLionel Sambuc return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6571f4a2713aSLionel Sambuc if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6572f4a2713aSLionel Sambuc return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6573f4a2713aSLionel Sambuc
6574f4a2713aSLionel Sambuc return 0;
6575f4a2713aSLionel Sambuc }
6576f4a2713aSLionel Sambuc
clang_Cursor_isVariadic(CXCursor C)6577f4a2713aSLionel Sambuc unsigned clang_Cursor_isVariadic(CXCursor C) {
6578f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
6579f4a2713aSLionel Sambuc return 0;
6580f4a2713aSLionel Sambuc
6581f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(C);
6582f4a2713aSLionel Sambuc if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6583f4a2713aSLionel Sambuc return FD->isVariadic();
6584f4a2713aSLionel Sambuc if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6585f4a2713aSLionel Sambuc return MD->isVariadic();
6586f4a2713aSLionel Sambuc
6587f4a2713aSLionel Sambuc return 0;
6588f4a2713aSLionel Sambuc }
6589f4a2713aSLionel Sambuc
clang_Cursor_getCommentRange(CXCursor C)6590f4a2713aSLionel Sambuc CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6591f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
6592f4a2713aSLionel Sambuc return clang_getNullRange();
6593f4a2713aSLionel Sambuc
6594f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(C);
6595f4a2713aSLionel Sambuc ASTContext &Context = getCursorContext(C);
6596f4a2713aSLionel Sambuc const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6597f4a2713aSLionel Sambuc if (!RC)
6598f4a2713aSLionel Sambuc return clang_getNullRange();
6599f4a2713aSLionel Sambuc
6600f4a2713aSLionel Sambuc return cxloc::translateSourceRange(Context, RC->getSourceRange());
6601f4a2713aSLionel Sambuc }
6602f4a2713aSLionel Sambuc
clang_Cursor_getRawCommentText(CXCursor C)6603f4a2713aSLionel Sambuc CXString clang_Cursor_getRawCommentText(CXCursor C) {
6604f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
6605f4a2713aSLionel Sambuc return cxstring::createNull();
6606f4a2713aSLionel Sambuc
6607f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(C);
6608f4a2713aSLionel Sambuc ASTContext &Context = getCursorContext(C);
6609f4a2713aSLionel Sambuc const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6610f4a2713aSLionel Sambuc StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6611f4a2713aSLionel Sambuc StringRef();
6612f4a2713aSLionel Sambuc
6613f4a2713aSLionel Sambuc // Don't duplicate the string because RawText points directly into source
6614f4a2713aSLionel Sambuc // code.
6615f4a2713aSLionel Sambuc return cxstring::createRef(RawText);
6616f4a2713aSLionel Sambuc }
6617f4a2713aSLionel Sambuc
clang_Cursor_getBriefCommentText(CXCursor C)6618f4a2713aSLionel Sambuc CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6619f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
6620f4a2713aSLionel Sambuc return cxstring::createNull();
6621f4a2713aSLionel Sambuc
6622f4a2713aSLionel Sambuc const Decl *D = getCursorDecl(C);
6623f4a2713aSLionel Sambuc const ASTContext &Context = getCursorContext(C);
6624f4a2713aSLionel Sambuc const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6625f4a2713aSLionel Sambuc
6626f4a2713aSLionel Sambuc if (RC) {
6627f4a2713aSLionel Sambuc StringRef BriefText = RC->getBriefText(Context);
6628f4a2713aSLionel Sambuc
6629f4a2713aSLionel Sambuc // Don't duplicate the string because RawComment ensures that this memory
6630f4a2713aSLionel Sambuc // will not go away.
6631f4a2713aSLionel Sambuc return cxstring::createRef(BriefText);
6632f4a2713aSLionel Sambuc }
6633f4a2713aSLionel Sambuc
6634f4a2713aSLionel Sambuc return cxstring::createNull();
6635f4a2713aSLionel Sambuc }
6636f4a2713aSLionel Sambuc
clang_Cursor_getModule(CXCursor C)6637f4a2713aSLionel Sambuc CXModule clang_Cursor_getModule(CXCursor C) {
6638f4a2713aSLionel Sambuc if (C.kind == CXCursor_ModuleImportDecl) {
6639f4a2713aSLionel Sambuc if (const ImportDecl *ImportD =
6640f4a2713aSLionel Sambuc dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
6641f4a2713aSLionel Sambuc return ImportD->getImportedModule();
6642f4a2713aSLionel Sambuc }
6643f4a2713aSLionel Sambuc
6644*0a6a1f1dSLionel Sambuc return nullptr;
6645*0a6a1f1dSLionel Sambuc }
6646*0a6a1f1dSLionel Sambuc
clang_getModuleForFile(CXTranslationUnit TU,CXFile File)6647*0a6a1f1dSLionel Sambuc CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6648*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
6649*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
6650*0a6a1f1dSLionel Sambuc return nullptr;
6651*0a6a1f1dSLionel Sambuc }
6652*0a6a1f1dSLionel Sambuc if (!File)
6653*0a6a1f1dSLionel Sambuc return nullptr;
6654*0a6a1f1dSLionel Sambuc FileEntry *FE = static_cast<FileEntry *>(File);
6655*0a6a1f1dSLionel Sambuc
6656*0a6a1f1dSLionel Sambuc ASTUnit &Unit = *cxtu::getASTUnit(TU);
6657*0a6a1f1dSLionel Sambuc HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6658*0a6a1f1dSLionel Sambuc ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6659*0a6a1f1dSLionel Sambuc
6660*0a6a1f1dSLionel Sambuc return Header.getModule();
6661f4a2713aSLionel Sambuc }
6662f4a2713aSLionel Sambuc
clang_Module_getASTFile(CXModule CXMod)6663f4a2713aSLionel Sambuc CXFile clang_Module_getASTFile(CXModule CXMod) {
6664f4a2713aSLionel Sambuc if (!CXMod)
6665*0a6a1f1dSLionel Sambuc return nullptr;
6666f4a2713aSLionel Sambuc Module *Mod = static_cast<Module*>(CXMod);
6667f4a2713aSLionel Sambuc return const_cast<FileEntry *>(Mod->getASTFile());
6668f4a2713aSLionel Sambuc }
6669f4a2713aSLionel Sambuc
clang_Module_getParent(CXModule CXMod)6670f4a2713aSLionel Sambuc CXModule clang_Module_getParent(CXModule CXMod) {
6671f4a2713aSLionel Sambuc if (!CXMod)
6672*0a6a1f1dSLionel Sambuc return nullptr;
6673f4a2713aSLionel Sambuc Module *Mod = static_cast<Module*>(CXMod);
6674f4a2713aSLionel Sambuc return Mod->Parent;
6675f4a2713aSLionel Sambuc }
6676f4a2713aSLionel Sambuc
clang_Module_getName(CXModule CXMod)6677f4a2713aSLionel Sambuc CXString clang_Module_getName(CXModule CXMod) {
6678f4a2713aSLionel Sambuc if (!CXMod)
6679f4a2713aSLionel Sambuc return cxstring::createEmpty();
6680f4a2713aSLionel Sambuc Module *Mod = static_cast<Module*>(CXMod);
6681f4a2713aSLionel Sambuc return cxstring::createDup(Mod->Name);
6682f4a2713aSLionel Sambuc }
6683f4a2713aSLionel Sambuc
clang_Module_getFullName(CXModule CXMod)6684f4a2713aSLionel Sambuc CXString clang_Module_getFullName(CXModule CXMod) {
6685f4a2713aSLionel Sambuc if (!CXMod)
6686f4a2713aSLionel Sambuc return cxstring::createEmpty();
6687f4a2713aSLionel Sambuc Module *Mod = static_cast<Module*>(CXMod);
6688f4a2713aSLionel Sambuc return cxstring::createDup(Mod->getFullModuleName());
6689f4a2713aSLionel Sambuc }
6690f4a2713aSLionel Sambuc
clang_Module_isSystem(CXModule CXMod)6691*0a6a1f1dSLionel Sambuc int clang_Module_isSystem(CXModule CXMod) {
6692*0a6a1f1dSLionel Sambuc if (!CXMod)
6693*0a6a1f1dSLionel Sambuc return 0;
6694*0a6a1f1dSLionel Sambuc Module *Mod = static_cast<Module*>(CXMod);
6695*0a6a1f1dSLionel Sambuc return Mod->IsSystem;
6696*0a6a1f1dSLionel Sambuc }
6697*0a6a1f1dSLionel Sambuc
clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,CXModule CXMod)6698f4a2713aSLionel Sambuc unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6699f4a2713aSLionel Sambuc CXModule CXMod) {
6700*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
6701*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
6702*0a6a1f1dSLionel Sambuc return 0;
6703*0a6a1f1dSLionel Sambuc }
6704*0a6a1f1dSLionel Sambuc if (!CXMod)
6705f4a2713aSLionel Sambuc return 0;
6706f4a2713aSLionel Sambuc Module *Mod = static_cast<Module*>(CXMod);
6707f4a2713aSLionel Sambuc FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6708f4a2713aSLionel Sambuc ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6709f4a2713aSLionel Sambuc return TopHeaders.size();
6710f4a2713aSLionel Sambuc }
6711f4a2713aSLionel Sambuc
clang_Module_getTopLevelHeader(CXTranslationUnit TU,CXModule CXMod,unsigned Index)6712f4a2713aSLionel Sambuc CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6713f4a2713aSLionel Sambuc CXModule CXMod, unsigned Index) {
6714*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
6715*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
6716*0a6a1f1dSLionel Sambuc return nullptr;
6717*0a6a1f1dSLionel Sambuc }
6718*0a6a1f1dSLionel Sambuc if (!CXMod)
6719*0a6a1f1dSLionel Sambuc return nullptr;
6720f4a2713aSLionel Sambuc Module *Mod = static_cast<Module*>(CXMod);
6721f4a2713aSLionel Sambuc FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6722f4a2713aSLionel Sambuc
6723f4a2713aSLionel Sambuc ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6724f4a2713aSLionel Sambuc if (Index < TopHeaders.size())
6725f4a2713aSLionel Sambuc return const_cast<FileEntry *>(TopHeaders[Index]);
6726f4a2713aSLionel Sambuc
6727*0a6a1f1dSLionel Sambuc return nullptr;
6728f4a2713aSLionel Sambuc }
6729f4a2713aSLionel Sambuc
6730f4a2713aSLionel Sambuc } // end: extern "C"
6731f4a2713aSLionel Sambuc
6732f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6733f4a2713aSLionel Sambuc // C++ AST instrospection.
6734f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6735f4a2713aSLionel Sambuc
6736f4a2713aSLionel Sambuc extern "C" {
clang_CXXMethod_isPureVirtual(CXCursor C)6737f4a2713aSLionel Sambuc unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6738f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
6739f4a2713aSLionel Sambuc return 0;
6740f4a2713aSLionel Sambuc
6741f4a2713aSLionel Sambuc const Decl *D = cxcursor::getCursorDecl(C);
6742*0a6a1f1dSLionel Sambuc const CXXMethodDecl *Method =
6743*0a6a1f1dSLionel Sambuc D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
6744f4a2713aSLionel Sambuc return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6745f4a2713aSLionel Sambuc }
6746f4a2713aSLionel Sambuc
clang_CXXMethod_isConst(CXCursor C)6747*0a6a1f1dSLionel Sambuc unsigned clang_CXXMethod_isConst(CXCursor C) {
6748*0a6a1f1dSLionel Sambuc if (!clang_isDeclaration(C.kind))
6749*0a6a1f1dSLionel Sambuc return 0;
6750*0a6a1f1dSLionel Sambuc
6751*0a6a1f1dSLionel Sambuc const Decl *D = cxcursor::getCursorDecl(C);
6752*0a6a1f1dSLionel Sambuc const CXXMethodDecl *Method =
6753*0a6a1f1dSLionel Sambuc D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
6754*0a6a1f1dSLionel Sambuc return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6755*0a6a1f1dSLionel Sambuc }
6756*0a6a1f1dSLionel Sambuc
clang_CXXMethod_isStatic(CXCursor C)6757f4a2713aSLionel Sambuc unsigned clang_CXXMethod_isStatic(CXCursor C) {
6758f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
6759f4a2713aSLionel Sambuc return 0;
6760f4a2713aSLionel Sambuc
6761f4a2713aSLionel Sambuc const Decl *D = cxcursor::getCursorDecl(C);
6762*0a6a1f1dSLionel Sambuc const CXXMethodDecl *Method =
6763*0a6a1f1dSLionel Sambuc D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
6764f4a2713aSLionel Sambuc return (Method && Method->isStatic()) ? 1 : 0;
6765f4a2713aSLionel Sambuc }
6766f4a2713aSLionel Sambuc
clang_CXXMethod_isVirtual(CXCursor C)6767f4a2713aSLionel Sambuc unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6768f4a2713aSLionel Sambuc if (!clang_isDeclaration(C.kind))
6769f4a2713aSLionel Sambuc return 0;
6770f4a2713aSLionel Sambuc
6771f4a2713aSLionel Sambuc const Decl *D = cxcursor::getCursorDecl(C);
6772*0a6a1f1dSLionel Sambuc const CXXMethodDecl *Method =
6773*0a6a1f1dSLionel Sambuc D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
6774f4a2713aSLionel Sambuc return (Method && Method->isVirtual()) ? 1 : 0;
6775f4a2713aSLionel Sambuc }
6776f4a2713aSLionel Sambuc } // end: extern "C"
6777f4a2713aSLionel Sambuc
6778f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6779f4a2713aSLionel Sambuc // Attribute introspection.
6780f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6781f4a2713aSLionel Sambuc
6782f4a2713aSLionel Sambuc extern "C" {
clang_getIBOutletCollectionType(CXCursor C)6783f4a2713aSLionel Sambuc CXType clang_getIBOutletCollectionType(CXCursor C) {
6784f4a2713aSLionel Sambuc if (C.kind != CXCursor_IBOutletCollectionAttr)
6785f4a2713aSLionel Sambuc return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6786f4a2713aSLionel Sambuc
6787f4a2713aSLionel Sambuc const IBOutletCollectionAttr *A =
6788f4a2713aSLionel Sambuc cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6789f4a2713aSLionel Sambuc
6790f4a2713aSLionel Sambuc return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6791f4a2713aSLionel Sambuc }
6792f4a2713aSLionel Sambuc } // end: extern "C"
6793f4a2713aSLionel Sambuc
6794f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6795f4a2713aSLionel Sambuc // Inspecting memory usage.
6796f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6797f4a2713aSLionel Sambuc
6798f4a2713aSLionel Sambuc typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6799f4a2713aSLionel Sambuc
createCXTUResourceUsageEntry(MemUsageEntries & entries,enum CXTUResourceUsageKind k,unsigned long amount)6800f4a2713aSLionel Sambuc static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6801f4a2713aSLionel Sambuc enum CXTUResourceUsageKind k,
6802f4a2713aSLionel Sambuc unsigned long amount) {
6803f4a2713aSLionel Sambuc CXTUResourceUsageEntry entry = { k, amount };
6804f4a2713aSLionel Sambuc entries.push_back(entry);
6805f4a2713aSLionel Sambuc }
6806f4a2713aSLionel Sambuc
6807f4a2713aSLionel Sambuc extern "C" {
6808f4a2713aSLionel Sambuc
clang_getTUResourceUsageName(CXTUResourceUsageKind kind)6809f4a2713aSLionel Sambuc const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6810f4a2713aSLionel Sambuc const char *str = "";
6811f4a2713aSLionel Sambuc switch (kind) {
6812f4a2713aSLionel Sambuc case CXTUResourceUsage_AST:
6813f4a2713aSLionel Sambuc str = "ASTContext: expressions, declarations, and types";
6814f4a2713aSLionel Sambuc break;
6815f4a2713aSLionel Sambuc case CXTUResourceUsage_Identifiers:
6816f4a2713aSLionel Sambuc str = "ASTContext: identifiers";
6817f4a2713aSLionel Sambuc break;
6818f4a2713aSLionel Sambuc case CXTUResourceUsage_Selectors:
6819f4a2713aSLionel Sambuc str = "ASTContext: selectors";
6820f4a2713aSLionel Sambuc break;
6821f4a2713aSLionel Sambuc case CXTUResourceUsage_GlobalCompletionResults:
6822f4a2713aSLionel Sambuc str = "Code completion: cached global results";
6823f4a2713aSLionel Sambuc break;
6824f4a2713aSLionel Sambuc case CXTUResourceUsage_SourceManagerContentCache:
6825f4a2713aSLionel Sambuc str = "SourceManager: content cache allocator";
6826f4a2713aSLionel Sambuc break;
6827f4a2713aSLionel Sambuc case CXTUResourceUsage_AST_SideTables:
6828f4a2713aSLionel Sambuc str = "ASTContext: side tables";
6829f4a2713aSLionel Sambuc break;
6830f4a2713aSLionel Sambuc case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6831f4a2713aSLionel Sambuc str = "SourceManager: malloc'ed memory buffers";
6832f4a2713aSLionel Sambuc break;
6833f4a2713aSLionel Sambuc case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6834f4a2713aSLionel Sambuc str = "SourceManager: mmap'ed memory buffers";
6835f4a2713aSLionel Sambuc break;
6836f4a2713aSLionel Sambuc case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6837f4a2713aSLionel Sambuc str = "ExternalASTSource: malloc'ed memory buffers";
6838f4a2713aSLionel Sambuc break;
6839f4a2713aSLionel Sambuc case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6840f4a2713aSLionel Sambuc str = "ExternalASTSource: mmap'ed memory buffers";
6841f4a2713aSLionel Sambuc break;
6842f4a2713aSLionel Sambuc case CXTUResourceUsage_Preprocessor:
6843f4a2713aSLionel Sambuc str = "Preprocessor: malloc'ed memory";
6844f4a2713aSLionel Sambuc break;
6845f4a2713aSLionel Sambuc case CXTUResourceUsage_PreprocessingRecord:
6846f4a2713aSLionel Sambuc str = "Preprocessor: PreprocessingRecord";
6847f4a2713aSLionel Sambuc break;
6848f4a2713aSLionel Sambuc case CXTUResourceUsage_SourceManager_DataStructures:
6849f4a2713aSLionel Sambuc str = "SourceManager: data structures and tables";
6850f4a2713aSLionel Sambuc break;
6851f4a2713aSLionel Sambuc case CXTUResourceUsage_Preprocessor_HeaderSearch:
6852f4a2713aSLionel Sambuc str = "Preprocessor: header search tables";
6853f4a2713aSLionel Sambuc break;
6854f4a2713aSLionel Sambuc }
6855f4a2713aSLionel Sambuc return str;
6856f4a2713aSLionel Sambuc }
6857f4a2713aSLionel Sambuc
clang_getCXTUResourceUsage(CXTranslationUnit TU)6858f4a2713aSLionel Sambuc CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6859*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
6860*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
6861*0a6a1f1dSLionel Sambuc CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
6862f4a2713aSLionel Sambuc return usage;
6863f4a2713aSLionel Sambuc }
6864f4a2713aSLionel Sambuc
6865f4a2713aSLionel Sambuc ASTUnit *astUnit = cxtu::getASTUnit(TU);
6866*0a6a1f1dSLionel Sambuc std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
6867f4a2713aSLionel Sambuc ASTContext &astContext = astUnit->getASTContext();
6868f4a2713aSLionel Sambuc
6869f4a2713aSLionel Sambuc // How much memory is used by AST nodes and types?
6870f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6871f4a2713aSLionel Sambuc (unsigned long) astContext.getASTAllocatedMemory());
6872f4a2713aSLionel Sambuc
6873f4a2713aSLionel Sambuc // How much memory is used by identifiers?
6874f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6875f4a2713aSLionel Sambuc (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6876f4a2713aSLionel Sambuc
6877f4a2713aSLionel Sambuc // How much memory is used for selectors?
6878f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6879f4a2713aSLionel Sambuc (unsigned long) astContext.Selectors.getTotalMemory());
6880f4a2713aSLionel Sambuc
6881f4a2713aSLionel Sambuc // How much memory is used by ASTContext's side tables?
6882f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6883f4a2713aSLionel Sambuc (unsigned long) astContext.getSideTableAllocatedMemory());
6884f4a2713aSLionel Sambuc
6885f4a2713aSLionel Sambuc // How much memory is used for caching global code completion results?
6886f4a2713aSLionel Sambuc unsigned long completionBytes = 0;
6887f4a2713aSLionel Sambuc if (GlobalCodeCompletionAllocator *completionAllocator =
6888*0a6a1f1dSLionel Sambuc astUnit->getCachedCompletionAllocator().get()) {
6889f4a2713aSLionel Sambuc completionBytes = completionAllocator->getTotalMemory();
6890f4a2713aSLionel Sambuc }
6891f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries,
6892f4a2713aSLionel Sambuc CXTUResourceUsage_GlobalCompletionResults,
6893f4a2713aSLionel Sambuc completionBytes);
6894f4a2713aSLionel Sambuc
6895f4a2713aSLionel Sambuc // How much memory is being used by SourceManager's content cache?
6896f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries,
6897f4a2713aSLionel Sambuc CXTUResourceUsage_SourceManagerContentCache,
6898f4a2713aSLionel Sambuc (unsigned long) astContext.getSourceManager().getContentCacheSize());
6899f4a2713aSLionel Sambuc
6900f4a2713aSLionel Sambuc // How much memory is being used by the MemoryBuffer's in SourceManager?
6901f4a2713aSLionel Sambuc const SourceManager::MemoryBufferSizes &srcBufs =
6902f4a2713aSLionel Sambuc astUnit->getSourceManager().getMemoryBufferSizes();
6903f4a2713aSLionel Sambuc
6904f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries,
6905f4a2713aSLionel Sambuc CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6906f4a2713aSLionel Sambuc (unsigned long) srcBufs.malloc_bytes);
6907f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries,
6908f4a2713aSLionel Sambuc CXTUResourceUsage_SourceManager_Membuffer_MMap,
6909f4a2713aSLionel Sambuc (unsigned long) srcBufs.mmap_bytes);
6910f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries,
6911f4a2713aSLionel Sambuc CXTUResourceUsage_SourceManager_DataStructures,
6912f4a2713aSLionel Sambuc (unsigned long) astContext.getSourceManager()
6913f4a2713aSLionel Sambuc .getDataStructureSizes());
6914f4a2713aSLionel Sambuc
6915f4a2713aSLionel Sambuc // How much memory is being used by the ExternalASTSource?
6916f4a2713aSLionel Sambuc if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6917f4a2713aSLionel Sambuc const ExternalASTSource::MemoryBufferSizes &sizes =
6918f4a2713aSLionel Sambuc esrc->getMemoryBufferSizes();
6919f4a2713aSLionel Sambuc
6920f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries,
6921f4a2713aSLionel Sambuc CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6922f4a2713aSLionel Sambuc (unsigned long) sizes.malloc_bytes);
6923f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries,
6924f4a2713aSLionel Sambuc CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6925f4a2713aSLionel Sambuc (unsigned long) sizes.mmap_bytes);
6926f4a2713aSLionel Sambuc }
6927f4a2713aSLionel Sambuc
6928f4a2713aSLionel Sambuc // How much memory is being used by the Preprocessor?
6929f4a2713aSLionel Sambuc Preprocessor &pp = astUnit->getPreprocessor();
6930f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries,
6931f4a2713aSLionel Sambuc CXTUResourceUsage_Preprocessor,
6932f4a2713aSLionel Sambuc pp.getTotalMemory());
6933f4a2713aSLionel Sambuc
6934f4a2713aSLionel Sambuc if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6935f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries,
6936f4a2713aSLionel Sambuc CXTUResourceUsage_PreprocessingRecord,
6937f4a2713aSLionel Sambuc pRec->getTotalMemory());
6938f4a2713aSLionel Sambuc }
6939f4a2713aSLionel Sambuc
6940f4a2713aSLionel Sambuc createCXTUResourceUsageEntry(*entries,
6941f4a2713aSLionel Sambuc CXTUResourceUsage_Preprocessor_HeaderSearch,
6942f4a2713aSLionel Sambuc pp.getHeaderSearchInfo().getTotalMemory());
6943f4a2713aSLionel Sambuc
6944f4a2713aSLionel Sambuc CXTUResourceUsage usage = { (void*) entries.get(),
6945f4a2713aSLionel Sambuc (unsigned) entries->size(),
6946*0a6a1f1dSLionel Sambuc entries->size() ? &(*entries)[0] : nullptr };
6947*0a6a1f1dSLionel Sambuc entries.release();
6948f4a2713aSLionel Sambuc return usage;
6949f4a2713aSLionel Sambuc }
6950f4a2713aSLionel Sambuc
clang_disposeCXTUResourceUsage(CXTUResourceUsage usage)6951f4a2713aSLionel Sambuc void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6952f4a2713aSLionel Sambuc if (usage.data)
6953f4a2713aSLionel Sambuc delete (MemUsageEntries*) usage.data;
6954f4a2713aSLionel Sambuc }
6955f4a2713aSLionel Sambuc
clang_getSkippedRanges(CXTranslationUnit TU,CXFile file)6956*0a6a1f1dSLionel Sambuc CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6957*0a6a1f1dSLionel Sambuc CXSourceRangeList *skipped = new CXSourceRangeList;
6958*0a6a1f1dSLionel Sambuc skipped->count = 0;
6959*0a6a1f1dSLionel Sambuc skipped->ranges = nullptr;
6960*0a6a1f1dSLionel Sambuc
6961*0a6a1f1dSLionel Sambuc if (isNotUsableTU(TU)) {
6962*0a6a1f1dSLionel Sambuc LOG_BAD_TU(TU);
6963*0a6a1f1dSLionel Sambuc return skipped;
6964*0a6a1f1dSLionel Sambuc }
6965*0a6a1f1dSLionel Sambuc
6966*0a6a1f1dSLionel Sambuc if (!file)
6967*0a6a1f1dSLionel Sambuc return skipped;
6968*0a6a1f1dSLionel Sambuc
6969*0a6a1f1dSLionel Sambuc ASTUnit *astUnit = cxtu::getASTUnit(TU);
6970*0a6a1f1dSLionel Sambuc PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6971*0a6a1f1dSLionel Sambuc if (!ppRec)
6972*0a6a1f1dSLionel Sambuc return skipped;
6973*0a6a1f1dSLionel Sambuc
6974*0a6a1f1dSLionel Sambuc ASTContext &Ctx = astUnit->getASTContext();
6975*0a6a1f1dSLionel Sambuc SourceManager &sm = Ctx.getSourceManager();
6976*0a6a1f1dSLionel Sambuc FileEntry *fileEntry = static_cast<FileEntry *>(file);
6977*0a6a1f1dSLionel Sambuc FileID wantedFileID = sm.translateFile(fileEntry);
6978*0a6a1f1dSLionel Sambuc
6979*0a6a1f1dSLionel Sambuc const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6980*0a6a1f1dSLionel Sambuc std::vector<SourceRange> wantedRanges;
6981*0a6a1f1dSLionel Sambuc for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6982*0a6a1f1dSLionel Sambuc i != ei; ++i) {
6983*0a6a1f1dSLionel Sambuc if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6984*0a6a1f1dSLionel Sambuc wantedRanges.push_back(*i);
6985*0a6a1f1dSLionel Sambuc }
6986*0a6a1f1dSLionel Sambuc
6987*0a6a1f1dSLionel Sambuc skipped->count = wantedRanges.size();
6988*0a6a1f1dSLionel Sambuc skipped->ranges = new CXSourceRange[skipped->count];
6989*0a6a1f1dSLionel Sambuc for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6990*0a6a1f1dSLionel Sambuc skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6991*0a6a1f1dSLionel Sambuc
6992*0a6a1f1dSLionel Sambuc return skipped;
6993*0a6a1f1dSLionel Sambuc }
6994*0a6a1f1dSLionel Sambuc
clang_disposeSourceRangeList(CXSourceRangeList * ranges)6995*0a6a1f1dSLionel Sambuc void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6996*0a6a1f1dSLionel Sambuc if (ranges) {
6997*0a6a1f1dSLionel Sambuc delete[] ranges->ranges;
6998*0a6a1f1dSLionel Sambuc delete ranges;
6999*0a6a1f1dSLionel Sambuc }
7000*0a6a1f1dSLionel Sambuc }
7001*0a6a1f1dSLionel Sambuc
7002f4a2713aSLionel Sambuc } // end extern "C"
7003f4a2713aSLionel Sambuc
PrintLibclangResourceUsage(CXTranslationUnit TU)7004f4a2713aSLionel Sambuc void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7005f4a2713aSLionel Sambuc CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7006f4a2713aSLionel Sambuc for (unsigned I = 0; I != Usage.numEntries; ++I)
7007f4a2713aSLionel Sambuc fprintf(stderr, " %s: %lu\n",
7008f4a2713aSLionel Sambuc clang_getTUResourceUsageName(Usage.entries[I].kind),
7009f4a2713aSLionel Sambuc Usage.entries[I].amount);
7010f4a2713aSLionel Sambuc
7011f4a2713aSLionel Sambuc clang_disposeCXTUResourceUsage(Usage);
7012f4a2713aSLionel Sambuc }
7013f4a2713aSLionel Sambuc
7014f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
7015f4a2713aSLionel Sambuc // Misc. utility functions.
7016f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
7017f4a2713aSLionel Sambuc
7018f4a2713aSLionel Sambuc /// Default to using an 8 MB stack size on "safety" threads.
7019f4a2713aSLionel Sambuc static unsigned SafetyStackThreadSize = 8 << 20;
7020f4a2713aSLionel Sambuc
7021f4a2713aSLionel Sambuc namespace clang {
7022f4a2713aSLionel Sambuc
RunSafely(llvm::CrashRecoveryContext & CRC,void (* Fn)(void *),void * UserData,unsigned Size)7023f4a2713aSLionel Sambuc bool RunSafely(llvm::CrashRecoveryContext &CRC,
7024f4a2713aSLionel Sambuc void (*Fn)(void*), void *UserData,
7025f4a2713aSLionel Sambuc unsigned Size) {
7026f4a2713aSLionel Sambuc if (!Size)
7027f4a2713aSLionel Sambuc Size = GetSafetyThreadStackSize();
7028f4a2713aSLionel Sambuc if (Size)
7029f4a2713aSLionel Sambuc return CRC.RunSafelyOnThread(Fn, UserData, Size);
7030f4a2713aSLionel Sambuc return CRC.RunSafely(Fn, UserData);
7031f4a2713aSLionel Sambuc }
7032f4a2713aSLionel Sambuc
GetSafetyThreadStackSize()7033f4a2713aSLionel Sambuc unsigned GetSafetyThreadStackSize() {
7034f4a2713aSLionel Sambuc return SafetyStackThreadSize;
7035f4a2713aSLionel Sambuc }
7036f4a2713aSLionel Sambuc
SetSafetyThreadStackSize(unsigned Value)7037f4a2713aSLionel Sambuc void SetSafetyThreadStackSize(unsigned Value) {
7038f4a2713aSLionel Sambuc SafetyStackThreadSize = Value;
7039f4a2713aSLionel Sambuc }
7040f4a2713aSLionel Sambuc
7041f4a2713aSLionel Sambuc }
7042f4a2713aSLionel Sambuc
setThreadBackgroundPriority()7043f4a2713aSLionel Sambuc void clang::setThreadBackgroundPriority() {
7044f4a2713aSLionel Sambuc if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7045f4a2713aSLionel Sambuc return;
7046f4a2713aSLionel Sambuc
7047*0a6a1f1dSLionel Sambuc #ifdef USE_DARWIN_THREADS
7048f4a2713aSLionel Sambuc setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7049f4a2713aSLionel Sambuc #endif
7050f4a2713aSLionel Sambuc }
7051f4a2713aSLionel Sambuc
printDiagsToStderr(ASTUnit * Unit)7052f4a2713aSLionel Sambuc void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7053f4a2713aSLionel Sambuc if (!Unit)
7054f4a2713aSLionel Sambuc return;
7055f4a2713aSLionel Sambuc
7056f4a2713aSLionel Sambuc for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7057f4a2713aSLionel Sambuc DEnd = Unit->stored_diag_end();
7058f4a2713aSLionel Sambuc D != DEnd; ++D) {
7059*0a6a1f1dSLionel Sambuc CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
7060f4a2713aSLionel Sambuc CXString Msg = clang_formatDiagnostic(&Diag,
7061f4a2713aSLionel Sambuc clang_defaultDiagnosticDisplayOptions());
7062f4a2713aSLionel Sambuc fprintf(stderr, "%s\n", clang_getCString(Msg));
7063f4a2713aSLionel Sambuc clang_disposeString(Msg);
7064f4a2713aSLionel Sambuc }
7065f4a2713aSLionel Sambuc #ifdef LLVM_ON_WIN32
7066f4a2713aSLionel Sambuc // On Windows, force a flush, since there may be multiple copies of
7067f4a2713aSLionel Sambuc // stderr and stdout in the file system, all with different buffers
7068f4a2713aSLionel Sambuc // but writing to the same device.
7069f4a2713aSLionel Sambuc fflush(stderr);
7070f4a2713aSLionel Sambuc #endif
7071f4a2713aSLionel Sambuc }
7072f4a2713aSLionel Sambuc
getMacroInfo(const IdentifierInfo & II,SourceLocation MacroDefLoc,CXTranslationUnit TU)7073f4a2713aSLionel Sambuc MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7074f4a2713aSLionel Sambuc SourceLocation MacroDefLoc,
7075f4a2713aSLionel Sambuc CXTranslationUnit TU){
7076f4a2713aSLionel Sambuc if (MacroDefLoc.isInvalid() || !TU)
7077*0a6a1f1dSLionel Sambuc return nullptr;
7078f4a2713aSLionel Sambuc if (!II.hadMacroDefinition())
7079*0a6a1f1dSLionel Sambuc return nullptr;
7080f4a2713aSLionel Sambuc
7081f4a2713aSLionel Sambuc ASTUnit *Unit = cxtu::getASTUnit(TU);
7082f4a2713aSLionel Sambuc Preprocessor &PP = Unit->getPreprocessor();
7083f4a2713aSLionel Sambuc MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
7084f4a2713aSLionel Sambuc if (MD) {
7085f4a2713aSLionel Sambuc for (MacroDirective::DefInfo
7086f4a2713aSLionel Sambuc Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7087f4a2713aSLionel Sambuc if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7088f4a2713aSLionel Sambuc return Def.getMacroInfo();
7089f4a2713aSLionel Sambuc }
7090f4a2713aSLionel Sambuc }
7091f4a2713aSLionel Sambuc
7092*0a6a1f1dSLionel Sambuc return nullptr;
7093f4a2713aSLionel Sambuc }
7094f4a2713aSLionel Sambuc
getMacroInfo(const MacroDefinition * MacroDef,CXTranslationUnit TU)7095f4a2713aSLionel Sambuc const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7096f4a2713aSLionel Sambuc CXTranslationUnit TU) {
7097f4a2713aSLionel Sambuc if (!MacroDef || !TU)
7098*0a6a1f1dSLionel Sambuc return nullptr;
7099f4a2713aSLionel Sambuc const IdentifierInfo *II = MacroDef->getName();
7100f4a2713aSLionel Sambuc if (!II)
7101*0a6a1f1dSLionel Sambuc return nullptr;
7102f4a2713aSLionel Sambuc
7103f4a2713aSLionel Sambuc return getMacroInfo(*II, MacroDef->getLocation(), TU);
7104f4a2713aSLionel Sambuc }
7105f4a2713aSLionel Sambuc
checkForMacroInMacroDefinition(const MacroInfo * MI,const Token & Tok,CXTranslationUnit TU)7106f4a2713aSLionel Sambuc MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7107f4a2713aSLionel Sambuc const Token &Tok,
7108f4a2713aSLionel Sambuc CXTranslationUnit TU) {
7109f4a2713aSLionel Sambuc if (!MI || !TU)
7110*0a6a1f1dSLionel Sambuc return nullptr;
7111f4a2713aSLionel Sambuc if (Tok.isNot(tok::raw_identifier))
7112*0a6a1f1dSLionel Sambuc return nullptr;
7113f4a2713aSLionel Sambuc
7114f4a2713aSLionel Sambuc if (MI->getNumTokens() == 0)
7115*0a6a1f1dSLionel Sambuc return nullptr;
7116f4a2713aSLionel Sambuc SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7117f4a2713aSLionel Sambuc MI->getDefinitionEndLoc());
7118f4a2713aSLionel Sambuc ASTUnit *Unit = cxtu::getASTUnit(TU);
7119f4a2713aSLionel Sambuc
7120f4a2713aSLionel Sambuc // Check that the token is inside the definition and not its argument list.
7121f4a2713aSLionel Sambuc SourceManager &SM = Unit->getSourceManager();
7122f4a2713aSLionel Sambuc if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
7123*0a6a1f1dSLionel Sambuc return nullptr;
7124f4a2713aSLionel Sambuc if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
7125*0a6a1f1dSLionel Sambuc return nullptr;
7126f4a2713aSLionel Sambuc
7127f4a2713aSLionel Sambuc Preprocessor &PP = Unit->getPreprocessor();
7128f4a2713aSLionel Sambuc PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7129f4a2713aSLionel Sambuc if (!PPRec)
7130*0a6a1f1dSLionel Sambuc return nullptr;
7131f4a2713aSLionel Sambuc
7132*0a6a1f1dSLionel Sambuc IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
7133f4a2713aSLionel Sambuc if (!II.hadMacroDefinition())
7134*0a6a1f1dSLionel Sambuc return nullptr;
7135f4a2713aSLionel Sambuc
7136f4a2713aSLionel Sambuc // Check that the identifier is not one of the macro arguments.
7137f4a2713aSLionel Sambuc if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
7138*0a6a1f1dSLionel Sambuc return nullptr;
7139f4a2713aSLionel Sambuc
7140f4a2713aSLionel Sambuc MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7141f4a2713aSLionel Sambuc if (!InnerMD)
7142*0a6a1f1dSLionel Sambuc return nullptr;
7143f4a2713aSLionel Sambuc
7144f4a2713aSLionel Sambuc return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
7145f4a2713aSLionel Sambuc }
7146f4a2713aSLionel Sambuc
checkForMacroInMacroDefinition(const MacroInfo * MI,SourceLocation Loc,CXTranslationUnit TU)7147f4a2713aSLionel Sambuc MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7148f4a2713aSLionel Sambuc SourceLocation Loc,
7149f4a2713aSLionel Sambuc CXTranslationUnit TU) {
7150f4a2713aSLionel Sambuc if (Loc.isInvalid() || !MI || !TU)
7151*0a6a1f1dSLionel Sambuc return nullptr;
7152f4a2713aSLionel Sambuc
7153f4a2713aSLionel Sambuc if (MI->getNumTokens() == 0)
7154*0a6a1f1dSLionel Sambuc return nullptr;
7155f4a2713aSLionel Sambuc ASTUnit *Unit = cxtu::getASTUnit(TU);
7156f4a2713aSLionel Sambuc Preprocessor &PP = Unit->getPreprocessor();
7157f4a2713aSLionel Sambuc if (!PP.getPreprocessingRecord())
7158*0a6a1f1dSLionel Sambuc return nullptr;
7159f4a2713aSLionel Sambuc Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7160f4a2713aSLionel Sambuc Token Tok;
7161f4a2713aSLionel Sambuc if (PP.getRawToken(Loc, Tok))
7162*0a6a1f1dSLionel Sambuc return nullptr;
7163f4a2713aSLionel Sambuc
7164f4a2713aSLionel Sambuc return checkForMacroInMacroDefinition(MI, Tok, TU);
7165f4a2713aSLionel Sambuc }
7166f4a2713aSLionel Sambuc
7167f4a2713aSLionel Sambuc extern "C" {
7168f4a2713aSLionel Sambuc
clang_getClangVersion()7169f4a2713aSLionel Sambuc CXString clang_getClangVersion() {
7170f4a2713aSLionel Sambuc return cxstring::createDup(getClangFullVersion());
7171f4a2713aSLionel Sambuc }
7172f4a2713aSLionel Sambuc
7173f4a2713aSLionel Sambuc } // end: extern "C"
7174f4a2713aSLionel Sambuc
operator <<(CXTranslationUnit TU)7175f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7176f4a2713aSLionel Sambuc if (TU) {
7177f4a2713aSLionel Sambuc if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
7178f4a2713aSLionel Sambuc LogOS << '<' << Unit->getMainFileName() << '>';
7179f4a2713aSLionel Sambuc if (Unit->isMainFileAST())
7180f4a2713aSLionel Sambuc LogOS << " (" << Unit->getASTFileName() << ')';
7181f4a2713aSLionel Sambuc return *this;
7182f4a2713aSLionel Sambuc }
7183*0a6a1f1dSLionel Sambuc } else {
7184f4a2713aSLionel Sambuc LogOS << "<NULL TU>";
7185*0a6a1f1dSLionel Sambuc }
7186f4a2713aSLionel Sambuc return *this;
7187f4a2713aSLionel Sambuc }
7188f4a2713aSLionel Sambuc
operator <<(const FileEntry * FE)7189f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7190f4a2713aSLionel Sambuc *this << FE->getName();
7191f4a2713aSLionel Sambuc return *this;
7192f4a2713aSLionel Sambuc }
7193f4a2713aSLionel Sambuc
operator <<(CXCursor cursor)7194f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7195f4a2713aSLionel Sambuc CXString cursorName = clang_getCursorDisplayName(cursor);
7196f4a2713aSLionel Sambuc *this << cursorName << "@" << clang_getCursorLocation(cursor);
7197f4a2713aSLionel Sambuc clang_disposeString(cursorName);
7198f4a2713aSLionel Sambuc return *this;
7199f4a2713aSLionel Sambuc }
7200f4a2713aSLionel Sambuc
operator <<(CXSourceLocation Loc)7201f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7202f4a2713aSLionel Sambuc CXFile File;
7203f4a2713aSLionel Sambuc unsigned Line, Column;
7204*0a6a1f1dSLionel Sambuc clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
7205f4a2713aSLionel Sambuc CXString FileName = clang_getFileName(File);
7206f4a2713aSLionel Sambuc *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7207f4a2713aSLionel Sambuc clang_disposeString(FileName);
7208f4a2713aSLionel Sambuc return *this;
7209f4a2713aSLionel Sambuc }
7210f4a2713aSLionel Sambuc
operator <<(CXSourceRange range)7211f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7212f4a2713aSLionel Sambuc CXSourceLocation BLoc = clang_getRangeStart(range);
7213f4a2713aSLionel Sambuc CXSourceLocation ELoc = clang_getRangeEnd(range);
7214f4a2713aSLionel Sambuc
7215f4a2713aSLionel Sambuc CXFile BFile;
7216f4a2713aSLionel Sambuc unsigned BLine, BColumn;
7217*0a6a1f1dSLionel Sambuc clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
7218f4a2713aSLionel Sambuc
7219f4a2713aSLionel Sambuc CXFile EFile;
7220f4a2713aSLionel Sambuc unsigned ELine, EColumn;
7221*0a6a1f1dSLionel Sambuc clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
7222f4a2713aSLionel Sambuc
7223f4a2713aSLionel Sambuc CXString BFileName = clang_getFileName(BFile);
7224f4a2713aSLionel Sambuc if (BFile == EFile) {
7225f4a2713aSLionel Sambuc *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7226f4a2713aSLionel Sambuc BLine, BColumn, ELine, EColumn);
7227f4a2713aSLionel Sambuc } else {
7228f4a2713aSLionel Sambuc CXString EFileName = clang_getFileName(EFile);
7229f4a2713aSLionel Sambuc *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7230f4a2713aSLionel Sambuc BLine, BColumn)
7231f4a2713aSLionel Sambuc << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7232f4a2713aSLionel Sambuc ELine, EColumn);
7233f4a2713aSLionel Sambuc clang_disposeString(EFileName);
7234f4a2713aSLionel Sambuc }
7235f4a2713aSLionel Sambuc clang_disposeString(BFileName);
7236f4a2713aSLionel Sambuc return *this;
7237f4a2713aSLionel Sambuc }
7238f4a2713aSLionel Sambuc
operator <<(CXString Str)7239f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(CXString Str) {
7240f4a2713aSLionel Sambuc *this << clang_getCString(Str);
7241f4a2713aSLionel Sambuc return *this;
7242f4a2713aSLionel Sambuc }
7243f4a2713aSLionel Sambuc
operator <<(const llvm::format_object_base & Fmt)7244f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7245f4a2713aSLionel Sambuc LogOS << Fmt;
7246f4a2713aSLionel Sambuc return *this;
7247f4a2713aSLionel Sambuc }
7248f4a2713aSLionel Sambuc
7249*0a6a1f1dSLionel Sambuc static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7250*0a6a1f1dSLionel Sambuc
~Logger()7251f4a2713aSLionel Sambuc cxindex::Logger::~Logger() {
7252f4a2713aSLionel Sambuc LogOS.flush();
7253f4a2713aSLionel Sambuc
7254*0a6a1f1dSLionel Sambuc llvm::sys::ScopedLock L(*LoggingMutex);
7255f4a2713aSLionel Sambuc
7256f4a2713aSLionel Sambuc static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7257f4a2713aSLionel Sambuc
7258f4a2713aSLionel Sambuc raw_ostream &OS = llvm::errs();
7259f4a2713aSLionel Sambuc OS << "[libclang:" << Name << ':';
7260f4a2713aSLionel Sambuc
7261*0a6a1f1dSLionel Sambuc #ifdef USE_DARWIN_THREADS
7262*0a6a1f1dSLionel Sambuc // TODO: Portability.
7263f4a2713aSLionel Sambuc mach_port_t tid = pthread_mach_thread_np(pthread_self());
7264f4a2713aSLionel Sambuc OS << tid << ':';
7265f4a2713aSLionel Sambuc #endif
7266f4a2713aSLionel Sambuc
7267f4a2713aSLionel Sambuc llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7268f4a2713aSLionel Sambuc OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7269f4a2713aSLionel Sambuc OS << Msg.str() << '\n';
7270f4a2713aSLionel Sambuc
7271f4a2713aSLionel Sambuc if (Trace) {
7272f4a2713aSLionel Sambuc llvm::sys::PrintStackTrace(stderr);
7273f4a2713aSLionel Sambuc OS << "--------------------------------------------------\n";
7274f4a2713aSLionel Sambuc }
7275f4a2713aSLionel Sambuc }
7276