blob: 2a9d96db4c35cb81b95f4c31379693556c2b3a2e [file] [log] [blame]
Ted Kremenekd2fa5662009-08-26 22:36:44 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00007//
Ted Kremenekd2fa5662009-08-26 22:36:44 +00008//===----------------------------------------------------------------------===//
9//
Ted Kremenekab188932010-01-05 19:32:54 +000010// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
Ted Kremenekd2fa5662009-08-26 22:36:44 +000012//
13//===----------------------------------------------------------------------===//
14
Ted Kremenekab188932010-01-05 19:32:54 +000015#include "CIndexer.h"
Ted Kremenek16c440a2010-01-15 20:35:54 +000016#include "CXCursor.h"
Ted Kremenek0a90d322010-11-17 23:24:11 +000017#include "CXTranslationUnit.h"
Ted Kremeneked122732010-11-16 01:56:27 +000018#include "CXString.h"
Ted Kremenek95f33552010-08-26 01:42:22 +000019#include "CXType.h"
Ted Kremeneka297de22010-01-25 22:34:44 +000020#include "CXSourceLocation.h"
Douglas Gregor5352ac02010-01-28 00:27:43 +000021#include "CIndexDiagnostic.h"
Ted Kremenekab188932010-01-05 19:32:54 +000022
Ted Kremenek04bb7162010-01-22 22:44:15 +000023#include "clang/Basic/Version.h"
Douglas Gregor936ea3b2010-01-28 00:56:43 +000024
Steve Naroff50398192009-08-28 15:28:48 +000025#include "clang/AST/DeclVisitor.h"
Steve Narofffb570422009-09-22 19:25:29 +000026#include "clang/AST/StmtVisitor.h"
Douglas Gregor7d0d40e2010-01-21 16:28:34 +000027#include "clang/AST/TypeLocVisitor.h"
Benjamin Kramerb846deb2010-04-12 19:45:50 +000028#include "clang/Basic/Diagnostic.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
Douglas Gregor936ea3b2010-01-28 00:56:43 +000031#include "clang/Frontend/FrontendDiagnostic.h"
Ted Kremenekd8210652010-01-06 23:43:31 +000032#include "clang/Lex/Lexer.h"
Douglas Gregordd3e5542011-05-04 00:14:37 +000033#include "clang/Lex/HeaderSearch.h"
Benjamin Kramerb846deb2010-04-12 19:45:50 +000034#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregor33e9abd2010-01-22 19:49:59 +000035#include "clang/Lex/Preprocessor.h"
Douglas Gregora67e03f2010-09-09 21:42:20 +000036#include "llvm/ADT/STLExtras.h"
Ted Kremenekd8c370c2010-11-02 23:10:24 +000037#include "llvm/ADT/Optional.h"
Douglas Gregorf5251602011-03-08 17:10:18 +000038#include "llvm/ADT/StringSwitch.h"
Ted Kremenekd8c370c2010-11-02 23:10:24 +000039#include "clang/Analysis/Support/SaveAndRestore.h"
Daniel Dunbarc7df4f32010-08-18 18:43:14 +000040#include "llvm/Support/CrashRecoveryContext.h"
Daniel Dunbar48615ff2010-10-08 19:30:33 +000041#include "llvm/Support/PrettyStackTrace.h"
Douglas Gregor02465752009-10-16 21:24:31 +000042#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor358559d2010-10-02 22:49:11 +000043#include "llvm/Support/raw_ostream.h"
Douglas Gregor7a07fcb2010-08-09 21:00:09 +000044#include "llvm/Support/Timer.h"
Michael J. Spencer03013fa2010-11-29 18:12:39 +000045#include "llvm/Support/Mutex.h"
46#include "llvm/Support/Program.h"
47#include "llvm/Support/Signals.h"
48#include "llvm/Support/Threading.h"
Ted Kremenek37f1ea02010-11-15 23:11:54 +000049#include "llvm/Support/Compiler.h"
Ted Kremenekfc062212009-10-19 21:44:57 +000050
Steve Naroff50398192009-08-28 15:28:48 +000051using namespace clang;
Ted Kremenek16c440a2010-01-15 20:35:54 +000052using namespace clang::cxcursor;
Ted Kremenekee4db4f2010-02-17 00:41:08 +000053using namespace clang::cxstring;
Steve Naroff50398192009-08-28 15:28:48 +000054
Ted Kremeneka60ed472010-11-16 08:15:36 +000055static CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) {
56 if (!TU)
57 return 0;
58 CXTranslationUnit D = new CXTranslationUnitImpl();
59 D->TUData = TU;
60 D->StringPool = createCXStringPool();
61 return D;
62}
63
Douglas Gregor33e9abd2010-01-22 19:49:59 +000064/// \brief The result of comparing two source ranges.
65enum RangeComparisonResult {
66 /// \brief Either the ranges overlap or one of the ranges is invalid.
67 RangeOverlap,
Ted Kremenekf0e23e82010-02-17 00:41:40 +000068
Douglas Gregor33e9abd2010-01-22 19:49:59 +000069 /// \brief The first range ends before the second range starts.
70 RangeBefore,
Ted Kremenekf0e23e82010-02-17 00:41:40 +000071
Douglas Gregor33e9abd2010-01-22 19:49:59 +000072 /// \brief The first range starts after the second range ends.
73 RangeAfter
74};
75
Ted Kremenekf0e23e82010-02-17 00:41:40 +000076/// \brief Compare two source ranges to determine their relative position in
Douglas Gregor33e9abd2010-01-22 19:49:59 +000077/// the translation unit.
Ted Kremenekf0e23e82010-02-17 00:41:40 +000078static RangeComparisonResult RangeCompare(SourceManager &SM,
79 SourceRange R1,
Douglas Gregor33e9abd2010-01-22 19:49:59 +000080 SourceRange R2) {
81 assert(R1.isValid() && "First range is invalid?");
82 assert(R2.isValid() && "Second range is invalid?");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000083 if (R1.getEnd() != R2.getBegin() &&
Daniel Dunbard52864b2010-02-14 10:02:57 +000084 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
Douglas Gregor33e9abd2010-01-22 19:49:59 +000085 return RangeBefore;
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000086 if (R2.getEnd() != R1.getBegin() &&
Daniel Dunbard52864b2010-02-14 10:02:57 +000087 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
Douglas Gregor33e9abd2010-01-22 19:49:59 +000088 return RangeAfter;
89 return RangeOverlap;
90}
91
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000092/// \brief Determine if a source location falls within, before, or after a
93/// a given source range.
94static RangeComparisonResult LocationCompare(SourceManager &SM,
95 SourceLocation L, SourceRange R) {
96 assert(R.isValid() && "First range is invalid?");
97 assert(L.isValid() && "Second range is invalid?");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000098 if (L == R.getBegin() || L == R.getEnd())
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000099 return RangeOverlap;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +0000100 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
101 return RangeBefore;
102 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
103 return RangeAfter;
104 return RangeOverlap;
105}
106
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000107/// \brief Translate a Clang source range into a CIndex source range.
108///
109/// Clang internally represents ranges where the end location points to the
110/// start of the token at the end. However, for external clients it is more
111/// useful to have a CXSourceRange be a proper half-open interval. This routine
112/// does the appropriate translation.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000113CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000114 const LangOptions &LangOpts,
Chris Lattner0a76aae2010-06-18 22:45:06 +0000115 const CharSourceRange &R) {
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000116 // We want the last character in this location, so we will adjust the
Douglas Gregor6a5a23f2010-03-19 21:51:54 +0000117 // location accordingly.
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000118 SourceLocation EndLoc = R.getEnd();
Douglas Gregora9b06d42010-11-09 06:24:54 +0000119 if (EndLoc.isValid() && EndLoc.isMacroID())
Douglas Gregorffcd9852011-04-20 21:16:21 +0000120 EndLoc = SM.getInstantiationRange(EndLoc).second;
Chris Lattner0a76aae2010-06-18 22:45:06 +0000121 if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +0000122 unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000123 EndLoc = EndLoc.getFileLocWithOffset(Length);
124 }
125
126 CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
127 R.getBegin().getRawEncoding(),
128 EndLoc.getRawEncoding() };
129 return Result;
130}
Douglas Gregor1db19de2010-01-19 21:36:55 +0000131
Ted Kremenek8a8da7d2010-01-06 03:42:32 +0000132//===----------------------------------------------------------------------===//
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000133// Cursor visitor.
Ted Kremenek8a8da7d2010-01-06 03:42:32 +0000134//===----------------------------------------------------------------------===//
135
Steve Naroff89922f82009-08-31 00:59:03 +0000136namespace {
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000137
138class VisitorJob {
139public:
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000140 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
Ted Kremeneke4979cc2010-11-13 00:58:18 +0000141 TypeLocVisitKind, OverloadExprPartsKind,
Ted Kremenek60608ec2010-11-17 00:50:47 +0000142 DeclRefExprPartsKind, LabelRefVisitKind,
Ted Kremenekf64d8032010-11-18 00:02:32 +0000143 ExplicitTemplateArgsVisitKind,
144 NestedNameSpecifierVisitKind,
Douglas Gregorf3db29f2011-02-25 18:19:59 +0000145 NestedNameSpecifierLocVisitKind,
Ted Kremenekcdba6592010-11-18 00:42:18 +0000146 DeclarationNameInfoVisitKind,
Douglas Gregor94d96292011-01-19 20:34:17 +0000147 MemberRefVisitKind, SizeOfPackExprPartsKind };
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000148protected:
Ted Kremenekf64d8032010-11-18 00:02:32 +0000149 void *data[3];
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000150 CXCursor parent;
151 Kind K;
Ted Kremenekf64d8032010-11-18 00:02:32 +0000152 VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
153 : parent(C), K(k) {
154 data[0] = d1;
155 data[1] = d2;
156 data[2] = d3;
157 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000158public:
159 Kind getKind() const { return K; }
160 const CXCursor &getParent() const { return parent; }
161 static bool classof(VisitorJob *VJ) { return true; }
162};
163
164typedef llvm::SmallVector<VisitorJob, 10> VisitorWorkList;
165
Douglas Gregorb1373d02010-01-20 20:59:29 +0000166// Cursor visitor.
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000167class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
Ted Kremenekcdba6592010-11-18 00:42:18 +0000168 public TypeLocVisitor<CursorVisitor, bool>
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000169{
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000170 /// \brief The translation unit we are traversing.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000171 CXTranslationUnit TU;
172 ASTUnit *AU;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000173
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000174 /// \brief The parent cursor whose children we are traversing.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000175 CXCursor Parent;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000176
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000177 /// \brief The declaration that serves at the parent of any statement or
178 /// expression nodes.
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000179 Decl *StmtParent;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000180
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000181 /// \brief The visitor function.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000182 CXCursorVisitor Visitor;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000183
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000184 /// \brief The opaque client data, to be passed along to the visitor.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000185 CXClientData ClientData;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000186
Douglas Gregor7d1d49d2009-10-16 20:01:17 +0000187 // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
188 // to the visitor. Declarations with a PCH level greater than this value will
189 // be suppressed.
190 unsigned MaxPCHLevel;
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000191
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000192 /// \brief Whether we should visit the preprocessing record entries last,
193 /// after visiting other declarations.
194 bool VisitPreprocessorLast;
195
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000196 /// \brief When valid, a source range to which the cursor should restrict
197 /// its search.
198 SourceRange RegionOfInterest;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000199
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000200 // FIXME: Eventually remove. This part of a hack to support proper
201 // iteration over all Decls contained lexically within an ObjC container.
202 DeclContext::decl_iterator *DI_current;
203 DeclContext::decl_iterator DE_current;
204
Ted Kremenekd1ded662010-11-15 23:31:32 +0000205 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
206 llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
207 llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
208
Douglas Gregorb1373d02010-01-20 20:59:29 +0000209 using DeclVisitor<CursorVisitor, bool>::Visit;
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000210 using TypeLocVisitor<CursorVisitor, bool>::Visit;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000211
212 /// \brief Determine whether this particular source range comes before, comes
213 /// after, or overlaps the region of interest.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000214 ///
Daniel Dunbard52864b2010-02-14 10:02:57 +0000215 /// \param R a half-open source range retrieved from the abstract syntax tree.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000216 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
217
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000218 class SetParentRAII {
219 CXCursor &Parent;
220 Decl *&StmtParent;
221 CXCursor OldParent;
222
223 public:
224 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
225 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
226 {
227 Parent = NewParent;
228 if (clang_isDeclaration(Parent.kind))
229 StmtParent = getCursorDecl(Parent);
230 }
231
232 ~SetParentRAII() {
233 Parent = OldParent;
234 if (clang_isDeclaration(Parent.kind))
235 StmtParent = getCursorDecl(Parent);
236 }
237 };
238
Steve Naroff89922f82009-08-31 00:59:03 +0000239public:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000240 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
241 CXClientData ClientData,
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000242 unsigned MaxPCHLevel,
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000243 bool VisitPreprocessorLast,
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000244 SourceRange RegionOfInterest = SourceRange())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000245 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
246 Visitor(Visitor), ClientData(ClientData),
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000247 MaxPCHLevel(MaxPCHLevel), VisitPreprocessorLast(VisitPreprocessorLast),
248 RegionOfInterest(RegionOfInterest), DI_current(0)
Douglas Gregorb1373d02010-01-20 20:59:29 +0000249 {
250 Parent.kind = CXCursor_NoDeclFound;
251 Parent.data[0] = 0;
252 Parent.data[1] = 0;
253 Parent.data[2] = 0;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000254 StmtParent = 0;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000255 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000256
Ted Kremenekd1ded662010-11-15 23:31:32 +0000257 ~CursorVisitor() {
258 // Free the pre-allocated worklists for data-recursion.
259 for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
260 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
261 delete *I;
262 }
263 }
264
Ted Kremeneka60ed472010-11-16 08:15:36 +0000265 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
266 CXTranslationUnit getTU() const { return TU; }
Ted Kremenekab979612010-11-11 08:05:23 +0000267
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000268 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000269
270 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
271 getPreprocessedEntities();
272
Douglas Gregorb1373d02010-01-20 20:59:29 +0000273 bool VisitChildren(CXCursor Parent);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000274
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000275 // Declaration visitors
Richard Smith162e1c12011-04-15 14:24:37 +0000276 bool VisitTypeAliasDecl(TypeAliasDecl *D);
Ted Kremenek09dfa372010-02-18 05:46:33 +0000277 bool VisitAttributes(Decl *D);
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000278 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenek3064ef92010-08-27 21:34:58 +0000279 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000280 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000281 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000282 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
283 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000284 bool VisitTagDecl(TagDecl *D);
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000285 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregor74dbe642010-08-31 19:31:58 +0000286 bool VisitClassTemplatePartialSpecializationDecl(
287 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000288 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000289 bool VisitEnumConstantDecl(EnumConstantDecl *D);
290 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
291 bool VisitFunctionDecl(FunctionDecl *ND);
292 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000293 bool VisitVarDecl(VarDecl *);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000294 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000295 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor39d6f072010-08-31 19:02:00 +0000296 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000297 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000298 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
299 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
300 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
301 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek23173d72010-05-18 21:09:07 +0000302 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremenek79758f62010-02-18 22:36:18 +0000303 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
304 bool VisitObjCImplDecl(ObjCImplDecl *D);
305 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
306 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000307 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
308 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
309 bool VisitObjCClassDecl(ObjCClassDecl *D);
Douglas Gregora4ffd852010-11-17 01:03:52 +0000310 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
Ted Kremeneka0536d82010-05-07 01:04:29 +0000311 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenek8f06e0e2010-05-06 23:38:21 +0000312 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregor69319002010-08-31 23:48:11 +0000313 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000314 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregor7e242562010-09-01 19:52:22 +0000315 bool VisitUsingDecl(UsingDecl *D);
316 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
317 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000318
Douglas Gregor01829d32010-08-31 14:41:23 +0000319 // Name visitor
320 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000321 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregordc355712011-02-25 00:36:19 +0000322 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
Douglas Gregor01829d32010-08-31 14:41:23 +0000323
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000324 // Template visitors
325 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregor0b36e612010-08-31 20:37:03 +0000326 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000327 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
328
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000329 // Type visitors
Douglas Gregor01829d32010-08-31 14:41:23 +0000330 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000331 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000332 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000333 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
334 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000335 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000336 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCallc12c5bb2010-05-15 11:32:37 +0000337 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000338 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
Abramo Bagnara075f8f12010-12-10 16:29:40 +0000339 bool VisitParenTypeLoc(ParenTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000340 bool VisitPointerTypeLoc(PointerTypeLoc TL);
341 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
342 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
343 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
344 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor01829d32010-08-31 14:41:23 +0000345 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000346 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000347 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000348 // FIXME: Implement visitors here when the unimplemented TypeLocs get
349 // implemented
350 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
Douglas Gregor7536dd52010-12-20 02:24:11 +0000351 bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000352 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Sean Huntca63c202011-05-24 22:41:36 +0000353 bool VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000354 bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
Douglas Gregor94fdffa2011-03-01 20:11:18 +0000355 bool VisitDependentTemplateSpecializationTypeLoc(
356 DependentTemplateSpecializationTypeLoc TL);
Douglas Gregor9e876872011-03-01 18:12:44 +0000357 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000358
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000359 // Data-recursive visitor functions.
360 bool IsInRegionOfInterest(CXCursor C);
361 bool RunVisitorWorkList(VisitorWorkList &WL);
362 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
Ted Kremenekcdba6592010-11-18 00:42:18 +0000363 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
Steve Naroff89922f82009-08-31 00:59:03 +0000364};
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000365
Ted Kremenekab188932010-01-05 19:32:54 +0000366} // end anonymous namespace
Benjamin Kramer5e4bc592009-10-18 16:11:04 +0000367
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000368static SourceRange getRawCursorExtent(CXCursor C);
Douglas Gregor66537982010-11-17 17:14:07 +0000369static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
370
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000371
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000372RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000373 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000374}
375
Douglas Gregorb1373d02010-01-20 20:59:29 +0000376/// \brief Visit the given cursor and, if requested by the visitor,
377/// its children.
378///
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000379/// \param Cursor the cursor to visit.
380///
381/// \param CheckRegionOfInterest if true, then the caller already checked that
382/// this cursor is within the region of interest.
383///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000384/// \returns true if the visitation should be aborted, false if it
385/// should continue.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000386bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregorb1373d02010-01-20 20:59:29 +0000387 if (clang_isInvalid(Cursor.kind))
388 return false;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000389
Douglas Gregorb1373d02010-01-20 20:59:29 +0000390 if (clang_isDeclaration(Cursor.kind)) {
391 Decl *D = getCursorDecl(Cursor);
392 assert(D && "Invalid declaration cursor");
393 if (D->getPCHLevel() > MaxPCHLevel)
394 return false;
395
396 if (D->isImplicit())
397 return false;
398 }
399
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000400 // If we have a range of interest, and this cursor doesn't intersect with it,
401 // we're done.
402 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000403 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbarf408f322010-02-14 08:32:05 +0000404 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000405 return false;
406 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000407
Douglas Gregorb1373d02010-01-20 20:59:29 +0000408 switch (Visitor(Cursor, Parent, ClientData)) {
409 case CXChildVisit_Break:
410 return true;
411
412 case CXChildVisit_Continue:
413 return false;
414
415 case CXChildVisit_Recurse:
416 return VisitChildren(Cursor);
417 }
418
Douglas Gregorfd643772010-01-25 16:45:46 +0000419 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000420}
421
Douglas Gregor788f5a12010-03-20 00:41:21 +0000422std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
423CursorVisitor::getPreprocessedEntities() {
424 PreprocessingRecord &PPRec
Ted Kremeneka60ed472010-11-16 08:15:36 +0000425 = *AU->getPreprocessor().getPreprocessingRecord();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000426
427 bool OnlyLocalDecls
Douglas Gregor32038bb2010-12-21 19:07:48 +0000428 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
429
430 if (OnlyLocalDecls && RegionOfInterest.isValid()) {
431 // If we would only look at local declarations but we have a region of
432 // interest, check whether that region of interest is in the main file.
433 // If not, we should traverse all declarations.
434 // FIXME: My kingdom for a proper binary search approach to finding
435 // cursors!
436 std::pair<FileID, unsigned> Location
437 = AU->getSourceManager().getDecomposedInstantiationLoc(
438 RegionOfInterest.getBegin());
439 if (Location.first != AU->getSourceManager().getMainFileID())
440 OnlyLocalDecls = false;
441 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000442
Douglas Gregor89d99802010-11-30 06:16:57 +0000443 PreprocessingRecord::iterator StartEntity, EndEntity;
444 if (OnlyLocalDecls) {
445 StartEntity = AU->pp_entity_begin();
446 EndEntity = AU->pp_entity_end();
447 } else {
448 StartEntity = PPRec.begin();
449 EndEntity = PPRec.end();
450 }
451
Douglas Gregor788f5a12010-03-20 00:41:21 +0000452 // There is no region of interest; we have to walk everything.
453 if (RegionOfInterest.isInvalid())
Douglas Gregor89d99802010-11-30 06:16:57 +0000454 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000455
456 // Find the file in which the region of interest lands.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000457 SourceManager &SM = AU->getSourceManager();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000458 std::pair<FileID, unsigned> Begin
459 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
460 std::pair<FileID, unsigned> End
461 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
462
463 // The region of interest spans files; we have to walk everything.
464 if (Begin.first != End.first)
Douglas Gregor89d99802010-11-30 06:16:57 +0000465 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000466
467 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
Ted Kremeneka60ed472010-11-16 08:15:36 +0000468 = AU->getPreprocessedEntitiesByFile();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000469 if (ByFileMap.empty()) {
470 // Build the mapping from files to sets of preprocessed entities.
Douglas Gregor89d99802010-11-30 06:16:57 +0000471 for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
Douglas Gregor788f5a12010-03-20 00:41:21 +0000472 std::pair<FileID, unsigned> P
473 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
Douglas Gregor89d99802010-11-30 06:16:57 +0000474
Douglas Gregor788f5a12010-03-20 00:41:21 +0000475 ByFileMap[P.first].push_back(*E);
476 }
477 }
478
479 return std::make_pair(ByFileMap[Begin.first].begin(),
480 ByFileMap[Begin.first].end());
481}
482
Douglas Gregorb1373d02010-01-20 20:59:29 +0000483/// \brief Visit the children of the given cursor.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000484///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000485/// \returns true if the visitation should be aborted, false if it
486/// should continue.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000487bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregorc314aa42011-03-02 19:17:03 +0000488 if (clang_isReference(Cursor.kind) &&
489 Cursor.kind != CXCursor_CXXBaseSpecifier) {
Douglas Gregora59e3902010-01-21 23:27:09 +0000490 // By definition, references have no children.
491 return false;
492 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000493
494 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregorb1373d02010-01-20 20:59:29 +0000495 // done.
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000496 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000497
Douglas Gregorb1373d02010-01-20 20:59:29 +0000498 if (clang_isDeclaration(Cursor.kind)) {
499 Decl *D = getCursorDecl(Cursor);
Douglas Gregor06d9b1a2011-04-14 21:41:34 +0000500 if (!D)
501 return false;
502
Ted Kremenek539311e2010-02-18 18:47:01 +0000503 return VisitAttributes(D) || Visit(D);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000504 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000505
Douglas Gregor06d9b1a2011-04-14 21:41:34 +0000506 if (clang_isStatement(Cursor.kind)) {
507 if (Stmt *S = getCursorStmt(Cursor))
508 return Visit(S);
509
510 return false;
511 }
512
513 if (clang_isExpression(Cursor.kind)) {
514 if (Expr *E = getCursorExpr(Cursor))
515 return Visit(E);
516
517 return false;
518 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000519
Douglas Gregorb1373d02010-01-20 20:59:29 +0000520 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000521 CXTranslationUnit tu = getCursorTU(Cursor);
522 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000523
524 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
525 for (unsigned I = 0; I != 2; ++I) {
526 if (VisitOrder[I]) {
527 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
528 RegionOfInterest.isInvalid()) {
529 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
530 TLEnd = CXXUnit->top_level_end();
531 TL != TLEnd; ++TL) {
532 if (Visit(MakeCXCursor(*TL, tu), true))
533 return true;
534 }
535 } else if (VisitDeclContext(
536 CXXUnit->getASTContext().getTranslationUnitDecl()))
Douglas Gregor7b691f332010-01-20 21:13:59 +0000537 return true;
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000538 continue;
Douglas Gregor7b691f332010-01-20 21:13:59 +0000539 }
Bob Wilson3178cb62010-03-19 03:57:57 +0000540
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000541 // Walk the preprocessing record.
542 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
543 // FIXME: Once we have the ability to deserialize a preprocessing record,
544 // do so.
545 PreprocessingRecord::iterator E, EEnd;
546 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
547 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
548 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
549 return true;
550
551 continue;
552 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000553
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000554 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
555 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
556 return true;
557
558 continue;
559 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000560
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000561 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
562 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
563 return true;
564
565 continue;
566 }
Douglas Gregorecdcb882010-10-20 22:00:55 +0000567 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000568 }
569 }
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000570
Douglas Gregor7b691f332010-01-20 21:13:59 +0000571 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000572 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000573
Douglas Gregorc314aa42011-03-02 19:17:03 +0000574 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
575 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
576 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
577 return Visit(BaseTSInfo->getTypeLoc());
578 }
579 }
580 }
581
Douglas Gregorb1373d02010-01-20 20:59:29 +0000582 // Nothing to visit at the moment.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000583 return false;
584}
585
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000586bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
Douglas Gregor13c8ccb2011-04-22 23:49:24 +0000587 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
588 if (Visit(TSInfo->getTypeLoc()))
589 return true;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000590
Ted Kremenek664cffd2010-07-22 11:30:19 +0000591 if (Stmt *Body = B->getBody())
592 return Visit(MakeCXCursor(Body, StmtParent, TU));
593
594 return false;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000595}
596
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000597llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
598 if (RegionOfInterest.isValid()) {
Douglas Gregor66537982010-11-17 17:14:07 +0000599 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000600 if (Range.isInvalid())
601 return llvm::Optional<bool>();
Douglas Gregor66537982010-11-17 17:14:07 +0000602
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000603 switch (CompareRegionOfInterest(Range)) {
604 case RangeBefore:
605 // This declaration comes before the region of interest; skip it.
606 return llvm::Optional<bool>();
607
608 case RangeAfter:
609 // This declaration comes after the region of interest; we're done.
610 return false;
611
612 case RangeOverlap:
613 // This declaration overlaps the region of interest; visit it.
614 break;
615 }
616 }
617 return true;
618}
619
620bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
621 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
622
623 // FIXME: Eventually remove. This part of a hack to support proper
624 // iteration over all Decls contained lexically within an ObjC container.
625 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
626 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
627
628 for ( ; I != E; ++I) {
Ted Kremenek23173d72010-05-18 21:09:07 +0000629 Decl *D = *I;
630 if (D->getLexicalDeclContext() != DC)
631 continue;
Ted Kremenek23173d72010-05-18 21:09:07 +0000632 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000633 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
634 if (!V.hasValue())
635 continue;
636 if (!V.getValue())
637 return false;
Daniel Dunbard52864b2010-02-14 10:02:57 +0000638 if (Visit(Cursor, true))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000639 return true;
640 }
Douglas Gregorb1373d02010-01-20 20:59:29 +0000641 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000642}
643
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000644bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
645 llvm_unreachable("Translation units are visited directly by Visit()");
646 return false;
647}
648
Richard Smith162e1c12011-04-15 14:24:37 +0000649bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
650 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
651 return Visit(TSInfo->getTypeLoc());
652
653 return false;
654}
655
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000656bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
657 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
658 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000659
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000660 return false;
661}
662
663bool CursorVisitor::VisitTagDecl(TagDecl *D) {
664 return VisitDeclContext(D);
665}
666
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000667bool CursorVisitor::VisitClassTemplateSpecializationDecl(
668 ClassTemplateSpecializationDecl *D) {
669 bool ShouldVisitBody = false;
670 switch (D->getSpecializationKind()) {
671 case TSK_Undeclared:
672 case TSK_ImplicitInstantiation:
673 // Nothing to visit
674 return false;
675
676 case TSK_ExplicitInstantiationDeclaration:
677 case TSK_ExplicitInstantiationDefinition:
678 break;
679
680 case TSK_ExplicitSpecialization:
681 ShouldVisitBody = true;
682 break;
683 }
684
685 // Visit the template arguments used in the specialization.
686 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
687 TypeLoc TL = SpecType->getTypeLoc();
688 if (TemplateSpecializationTypeLoc *TSTLoc
689 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
690 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
691 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
692 return true;
693 }
694 }
695
696 if (ShouldVisitBody && VisitCXXRecordDecl(D))
697 return true;
698
699 return false;
700}
701
Douglas Gregor74dbe642010-08-31 19:31:58 +0000702bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
703 ClassTemplatePartialSpecializationDecl *D) {
704 // FIXME: Visit the "outer" template parameter lists on the TagDecl
705 // before visiting these template parameters.
706 if (VisitTemplateParameters(D->getTemplateParameters()))
707 return true;
708
709 // Visit the partial specialization arguments.
710 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
711 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
712 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
713 return true;
714
715 return VisitCXXRecordDecl(D);
716}
717
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000718bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor84b51d72010-09-01 20:16:53 +0000719 // Visit the default argument.
720 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
721 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
722 if (Visit(DefArg->getTypeLoc()))
723 return true;
724
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000725 return false;
726}
727
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000728bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
729 if (Expr *Init = D->getInitExpr())
730 return Visit(MakeCXCursor(Init, StmtParent, TU));
731 return false;
732}
733
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000734bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
735 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
736 if (Visit(TSInfo->getTypeLoc()))
737 return true;
738
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000739 // Visit the nested-name-specifier, if present.
740 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
741 if (VisitNestedNameSpecifierLoc(QualifierLoc))
742 return true;
743
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000744 return false;
745}
746
Douglas Gregora67e03f2010-09-09 21:42:20 +0000747/// \brief Compare two base or member initializers based on their source order.
Sean Huntcbb67482011-01-08 20:30:50 +0000748static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
749 CXXCtorInitializer const * const *X
750 = static_cast<CXXCtorInitializer const * const *>(Xp);
751 CXXCtorInitializer const * const *Y
752 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000753
754 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
755 return -1;
756 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
757 return 1;
758 else
759 return 0;
760}
761
Douglas Gregorb1373d02010-01-20 20:59:29 +0000762bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor01829d32010-08-31 14:41:23 +0000763 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
764 // Visit the function declaration's syntactic components in the order
765 // written. This requires a bit of work.
Abramo Bagnara723df242010-12-14 22:11:44 +0000766 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor01829d32010-08-31 14:41:23 +0000767 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
768
769 // If we have a function declared directly (without the use of a typedef),
770 // visit just the return type. Otherwise, just visit the function's type
771 // now.
772 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
773 (!FTL && Visit(TL)))
774 return true;
775
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000776 // Visit the nested-name-specifier, if present.
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000777 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
778 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000779 return true;
Douglas Gregor01829d32010-08-31 14:41:23 +0000780
781 // Visit the declaration name.
782 if (VisitDeclarationNameInfo(ND->getNameInfo()))
783 return true;
784
785 // FIXME: Visit explicitly-specified template arguments!
786
787 // Visit the function parameters, if we have a function type.
788 if (FTL && VisitFunctionTypeLoc(*FTL, true))
789 return true;
790
791 // FIXME: Attributes?
792 }
793
Sean Hunt10620eb2011-05-06 20:44:56 +0000794 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
Douglas Gregora67e03f2010-09-09 21:42:20 +0000795 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
796 // Find the initializers that were written in the source.
Sean Huntcbb67482011-01-08 20:30:50 +0000797 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregora67e03f2010-09-09 21:42:20 +0000798 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
799 IEnd = Constructor->init_end();
800 I != IEnd; ++I) {
801 if (!(*I)->isWritten())
802 continue;
803
804 WrittenInits.push_back(*I);
805 }
806
807 // Sort the initializers in source order
808 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Sean Huntcbb67482011-01-08 20:30:50 +0000809 &CompareCXXCtorInitializers);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000810
811 // Visit the initializers in source order
812 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Sean Huntcbb67482011-01-08 20:30:50 +0000813 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichet00eb3f92010-12-04 09:14:42 +0000814 if (Init->isAnyMemberInitializer()) {
815 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregora67e03f2010-09-09 21:42:20 +0000816 Init->getMemberLocation(), TU)))
817 return true;
818 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
819 if (Visit(BaseInfo->getTypeLoc()))
820 return true;
821 }
822
823 // Visit the initializer value.
824 if (Expr *Initializer = Init->getInit())
825 if (Visit(MakeCXCursor(Initializer, ND, TU)))
826 return true;
827 }
828 }
829
830 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
831 return true;
832 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000833
Douglas Gregorb1373d02010-01-20 20:59:29 +0000834 return false;
835}
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000836
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000837bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
838 if (VisitDeclaratorDecl(D))
839 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000840
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000841 if (Expr *BitWidth = D->getBitWidth())
842 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000843
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000844 return false;
845}
846
847bool CursorVisitor::VisitVarDecl(VarDecl *D) {
848 if (VisitDeclaratorDecl(D))
849 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000850
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000851 if (Expr *Init = D->getInit())
852 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000853
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000854 return false;
855}
856
Douglas Gregor84b51d72010-09-01 20:16:53 +0000857bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
858 if (VisitDeclaratorDecl(D))
859 return true;
860
861 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
862 if (Expr *DefArg = D->getDefaultArgument())
863 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
864
865 return false;
866}
867
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000868bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
869 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
870 // before visiting these template parameters.
871 if (VisitTemplateParameters(D->getTemplateParameters()))
872 return true;
873
874 return VisitFunctionDecl(D->getTemplatedDecl());
875}
876
Douglas Gregor39d6f072010-08-31 19:02:00 +0000877bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
878 // FIXME: Visit the "outer" template parameter lists on the TagDecl
879 // before visiting these template parameters.
880 if (VisitTemplateParameters(D->getTemplateParameters()))
881 return true;
882
883 return VisitCXXRecordDecl(D->getTemplatedDecl());
884}
885
Douglas Gregor84b51d72010-09-01 20:16:53 +0000886bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
887 if (VisitTemplateParameters(D->getTemplateParameters()))
888 return true;
889
890 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
891 VisitTemplateArgumentLoc(D->getDefaultArgument()))
892 return true;
893
894 return false;
895}
896
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000897bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor4bc1cb62010-03-08 14:59:44 +0000898 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
899 if (Visit(TSInfo->getTypeLoc()))
900 return true;
901
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000902 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000903 PEnd = ND->param_end();
904 P != PEnd; ++P) {
905 if (Visit(MakeCXCursor(*P, TU)))
906 return true;
907 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000908
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000909 if (ND->isThisDeclarationADefinition() &&
910 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
911 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000912
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000913 return false;
914}
915
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000916namespace {
917 struct ContainerDeclsSort {
918 SourceManager &SM;
919 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
920 bool operator()(Decl *A, Decl *B) {
921 SourceLocation L_A = A->getLocStart();
922 SourceLocation L_B = B->getLocStart();
923 assert(L_A.isValid() && L_B.isValid());
924 return SM.isBeforeInTranslationUnit(L_A, L_B);
925 }
926 };
927}
928
Douglas Gregora59e3902010-01-21 23:27:09 +0000929bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000930 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
931 // an @implementation can lexically contain Decls that are not properly
932 // nested in the AST. When we identify such cases, we need to retrofit
933 // this nesting here.
934 if (!DI_current)
935 return VisitDeclContext(D);
936
937 // Scan the Decls that immediately come after the container
938 // in the current DeclContext. If any fall within the
939 // container's lexical region, stash them into a vector
940 // for later processing.
941 llvm::SmallVector<Decl *, 24> DeclsInContainer;
942 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000943 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000944 if (EndLoc.isValid()) {
945 DeclContext::decl_iterator next = *DI_current;
946 while (++next != DE_current) {
947 Decl *D_next = *next;
948 if (!D_next)
949 break;
950 SourceLocation L = D_next->getLocStart();
951 if (!L.isValid())
952 break;
953 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
954 *DI_current = next;
955 DeclsInContainer.push_back(D_next);
956 continue;
957 }
958 break;
959 }
960 }
961
962 // The common case.
963 if (DeclsInContainer.empty())
964 return VisitDeclContext(D);
965
966 // Get all the Decls in the DeclContext, and sort them with the
967 // additional ones we've collected. Then visit them.
968 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
969 I!=E; ++I) {
970 Decl *subDecl = *I;
Ted Kremenek0582c892010-11-02 23:17:51 +0000971 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
972 subDecl->getLocStart().isInvalid())
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000973 continue;
974 DeclsInContainer.push_back(subDecl);
975 }
976
977 // Now sort the Decls so that they appear in lexical order.
978 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
979 ContainerDeclsSort(SM));
980
981 // Now visit the decls.
982 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
983 E = DeclsInContainer.end(); I != E; ++I) {
984 CXCursor Cursor = MakeCXCursor(*I, TU);
985 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
986 if (!V.hasValue())
987 continue;
988 if (!V.getValue())
989 return false;
990 if (Visit(Cursor, true))
991 return true;
992 }
993 return false;
Douglas Gregora59e3902010-01-21 23:27:09 +0000994}
995
Douglas Gregorb1373d02010-01-20 20:59:29 +0000996bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000997 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
998 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000999 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001000
Douglas Gregor78db0cd2010-01-16 15:44:18 +00001001 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1002 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1003 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001004 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001005 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001006
Douglas Gregora59e3902010-01-21 23:27:09 +00001007 return VisitObjCContainerDecl(ND);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001008}
1009
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001010bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1011 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1012 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1013 E = PID->protocol_end(); I != E; ++I, ++PL)
1014 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1015 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001016
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001017 return VisitObjCContainerDecl(PID);
1018}
1019
Ted Kremenek23173d72010-05-18 21:09:07 +00001020bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor83cb9422010-09-09 17:09:21 +00001021 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCallfc929202010-06-04 22:33:30 +00001022 return true;
1023
Ted Kremenek23173d72010-05-18 21:09:07 +00001024 // FIXME: This implements a workaround with @property declarations also being
1025 // installed in the DeclContext for the @interface. Eventually this code
1026 // should be removed.
1027 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1028 if (!CDecl || !CDecl->IsClassExtension())
1029 return false;
1030
1031 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1032 if (!ID)
1033 return false;
1034
1035 IdentifierInfo *PropertyId = PD->getIdentifier();
1036 ObjCPropertyDecl *prevDecl =
1037 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1038
1039 if (!prevDecl)
1040 return false;
1041
1042 // Visit synthesized methods since they will be skipped when visiting
1043 // the @interface.
1044 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001045 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001046 if (Visit(MakeCXCursor(MD, TU)))
1047 return true;
1048
1049 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001050 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001051 if (Visit(MakeCXCursor(MD, TU)))
1052 return true;
1053
1054 return false;
1055}
1056
Douglas Gregorb1373d02010-01-20 20:59:29 +00001057bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001058 // Issue callbacks for super class.
Douglas Gregorb1373d02010-01-20 20:59:29 +00001059 if (D->getSuperClass() &&
1060 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001061 D->getSuperClassLoc(),
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001062 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001063 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001064
Douglas Gregor78db0cd2010-01-16 15:44:18 +00001065 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1066 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1067 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001068 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001069 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001070
Douglas Gregora59e3902010-01-21 23:27:09 +00001071 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001072}
1073
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001074bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1075 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001076}
1077
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001078bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremenekebfa3392010-03-19 20:39:03 +00001079 // 'ID' could be null when dealing with invalid code.
1080 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1081 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1082 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001083
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001084 return VisitObjCImplDecl(D);
1085}
1086
1087bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1088#if 0
1089 // Issue callbacks for super class.
1090 // FIXME: No source location information!
1091 if (D->getSuperClass() &&
1092 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001093 D->getSuperClassLoc(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001094 TU)))
1095 return true;
1096#endif
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001097
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001098 return VisitObjCImplDecl(D);
1099}
1100
1101bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1102 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1103 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1104 E = D->protocol_end();
1105 I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001106 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001107 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001108
1109 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001110}
1111
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001112bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1113 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1114 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1115 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001116
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001117 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001118}
1119
Douglas Gregora4ffd852010-11-17 01:03:52 +00001120bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1121 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1122 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1123
1124 return false;
1125}
1126
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00001127bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1128 return VisitDeclContext(D);
1129}
1130
Douglas Gregor69319002010-08-31 23:48:11 +00001131bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001132 // Visit nested-name-specifier.
Douglas Gregor0cfaf6a2011-02-25 17:08:07 +00001133 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1134 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001135 return true;
Douglas Gregor69319002010-08-31 23:48:11 +00001136
1137 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1138 D->getTargetNameLoc(), TU));
1139}
1140
Douglas Gregor7e242562010-09-01 19:52:22 +00001141bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001142 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001143 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1144 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001145 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001146 }
Douglas Gregor7e242562010-09-01 19:52:22 +00001147
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001148 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1149 return true;
1150
Douglas Gregor7e242562010-09-01 19:52:22 +00001151 return VisitDeclarationNameInfo(D->getNameInfo());
1152}
1153
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001154bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001155 // Visit nested-name-specifier.
Douglas Gregordb992412011-02-25 16:33:46 +00001156 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1157 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001158 return true;
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001159
1160 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1161 D->getIdentLocation(), TU));
1162}
1163
Douglas Gregor7e242562010-09-01 19:52:22 +00001164bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001165 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001168 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001169 }
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001170
Douglas Gregor7e242562010-09-01 19:52:22 +00001171 return VisitDeclarationNameInfo(D->getNameInfo());
1172}
1173
1174bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1175 UnresolvedUsingTypenameDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001176 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001177 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1178 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001179 return true;
1180
Douglas Gregor7e242562010-09-01 19:52:22 +00001181 return false;
1182}
1183
Douglas Gregor01829d32010-08-31 14:41:23 +00001184bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1185 switch (Name.getName().getNameKind()) {
1186 case clang::DeclarationName::Identifier:
1187 case clang::DeclarationName::CXXLiteralOperatorName:
1188 case clang::DeclarationName::CXXOperatorName:
1189 case clang::DeclarationName::CXXUsingDirective:
1190 return false;
1191
1192 case clang::DeclarationName::CXXConstructorName:
1193 case clang::DeclarationName::CXXDestructorName:
1194 case clang::DeclarationName::CXXConversionFunctionName:
1195 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1196 return Visit(TSInfo->getTypeLoc());
1197 return false;
1198
1199 case clang::DeclarationName::ObjCZeroArgSelector:
1200 case clang::DeclarationName::ObjCOneArgSelector:
1201 case clang::DeclarationName::ObjCMultiArgSelector:
1202 // FIXME: Per-identifier location info?
1203 return false;
1204 }
1205
1206 return false;
1207}
1208
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001209bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1210 SourceRange Range) {
1211 // FIXME: This whole routine is a hack to work around the lack of proper
1212 // source information in nested-name-specifiers (PR5791). Since we do have
1213 // a beginning source location, we can visit the first component of the
1214 // nested-name-specifier, if it's a single-token component.
1215 if (!NNS)
1216 return false;
1217
1218 // Get the first component in the nested-name-specifier.
1219 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1220 NNS = Prefix;
1221
1222 switch (NNS->getKind()) {
1223 case NestedNameSpecifier::Namespace:
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001224 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1225 TU));
1226
Douglas Gregor14aba762011-02-24 02:36:08 +00001227 case NestedNameSpecifier::NamespaceAlias:
1228 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1229 Range.getBegin(), TU));
1230
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001231 case NestedNameSpecifier::TypeSpec: {
1232 // If the type has a form where we know that the beginning of the source
1233 // range matches up with a reference cursor. Visit the appropriate reference
1234 // cursor.
John McCallf4c73712011-01-19 06:33:43 +00001235 const Type *T = NNS->getAsType();
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001236 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1237 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1238 if (const TagType *Tag = dyn_cast<TagType>(T))
1239 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1240 if (const TemplateSpecializationType *TST
1241 = dyn_cast<TemplateSpecializationType>(T))
1242 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1243 break;
1244 }
1245
1246 case NestedNameSpecifier::TypeSpecWithTemplate:
1247 case NestedNameSpecifier::Global:
1248 case NestedNameSpecifier::Identifier:
1249 break;
1250 }
1251
1252 return false;
1253}
1254
Douglas Gregordc355712011-02-25 00:36:19 +00001255bool
1256CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1257 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1258 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1259 Qualifiers.push_back(Qualifier);
1260
1261 while (!Qualifiers.empty()) {
1262 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1263 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1264 switch (NNS->getKind()) {
1265 case NestedNameSpecifier::Namespace:
1266 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001267 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001268 TU)))
1269 return true;
1270
1271 break;
1272
1273 case NestedNameSpecifier::NamespaceAlias:
1274 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001275 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001276 TU)))
1277 return true;
1278
1279 break;
1280
1281 case NestedNameSpecifier::TypeSpec:
1282 case NestedNameSpecifier::TypeSpecWithTemplate:
1283 if (Visit(Q.getTypeLoc()))
1284 return true;
1285
1286 break;
1287
1288 case NestedNameSpecifier::Global:
1289 case NestedNameSpecifier::Identifier:
1290 break;
1291 }
1292 }
1293
1294 return false;
1295}
1296
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001297bool CursorVisitor::VisitTemplateParameters(
1298 const TemplateParameterList *Params) {
1299 if (!Params)
1300 return false;
1301
1302 for (TemplateParameterList::const_iterator P = Params->begin(),
1303 PEnd = Params->end();
1304 P != PEnd; ++P) {
1305 if (Visit(MakeCXCursor(*P, TU)))
1306 return true;
1307 }
1308
1309 return false;
1310}
1311
Douglas Gregor0b36e612010-08-31 20:37:03 +00001312bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1313 switch (Name.getKind()) {
1314 case TemplateName::Template:
1315 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1316
1317 case TemplateName::OverloadedTemplate:
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001318 // Visit the overloaded template set.
1319 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1320 return true;
1321
Douglas Gregor0b36e612010-08-31 20:37:03 +00001322 return false;
1323
1324 case TemplateName::DependentTemplate:
1325 // FIXME: Visit nested-name-specifier.
1326 return false;
1327
1328 case TemplateName::QualifiedTemplate:
1329 // FIXME: Visit nested-name-specifier.
1330 return Visit(MakeCursorTemplateRef(
1331 Name.getAsQualifiedTemplateName()->getDecl(),
1332 Loc, TU));
Douglas Gregor1aee05d2011-01-15 06:45:20 +00001333
1334 case TemplateName::SubstTemplateTemplateParmPack:
1335 return Visit(MakeCursorTemplateRef(
1336 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1337 Loc, TU));
Douglas Gregor0b36e612010-08-31 20:37:03 +00001338 }
1339
1340 return false;
1341}
1342
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001343bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1344 switch (TAL.getArgument().getKind()) {
1345 case TemplateArgument::Null:
1346 case TemplateArgument::Integral:
Douglas Gregor87dd6972010-12-20 16:52:59 +00001347 case TemplateArgument::Pack:
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001348 return false;
1349
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001350 case TemplateArgument::Type:
1351 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1352 return Visit(TSInfo->getTypeLoc());
1353 return false;
1354
1355 case TemplateArgument::Declaration:
1356 if (Expr *E = TAL.getSourceDeclExpression())
1357 return Visit(MakeCXCursor(E, StmtParent, TU));
1358 return false;
1359
1360 case TemplateArgument::Expression:
1361 if (Expr *E = TAL.getSourceExpression())
1362 return Visit(MakeCXCursor(E, StmtParent, TU));
1363 return false;
1364
1365 case TemplateArgument::Template:
Douglas Gregora7fc9012011-01-05 18:58:31 +00001366 case TemplateArgument::TemplateExpansion:
Douglas Gregorb6744ef2011-03-02 17:09:35 +00001367 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1368 return true;
1369
Douglas Gregora7fc9012011-01-05 18:58:31 +00001370 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregor0b36e612010-08-31 20:37:03 +00001371 TAL.getTemplateNameLoc());
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001372 }
1373
1374 return false;
1375}
1376
Ted Kremeneka0536d82010-05-07 01:04:29 +00001377bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1378 return VisitDeclContext(D);
1379}
1380
Douglas Gregor01829d32010-08-31 14:41:23 +00001381bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1382 return Visit(TL.getUnqualifiedLoc());
1383}
1384
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001385bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00001386 ASTContext &Context = AU->getASTContext();
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001387
1388 // Some builtin types (such as Objective-C's "id", "sel", and
1389 // "Class") have associated declarations. Create cursors for those.
1390 QualType VisitType;
1391 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001392 case BuiltinType::Void:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001393 case BuiltinType::Bool:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001394 case BuiltinType::Char_U:
1395 case BuiltinType::UChar:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001396 case BuiltinType::Char16:
1397 case BuiltinType::Char32:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001398 case BuiltinType::UShort:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001399 case BuiltinType::UInt:
1400 case BuiltinType::ULong:
1401 case BuiltinType::ULongLong:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001402 case BuiltinType::UInt128:
1403 case BuiltinType::Char_S:
1404 case BuiltinType::SChar:
Chris Lattner3f59c972010-12-25 23:25:43 +00001405 case BuiltinType::WChar_U:
1406 case BuiltinType::WChar_S:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001407 case BuiltinType::Short:
1408 case BuiltinType::Int:
1409 case BuiltinType::Long:
1410 case BuiltinType::LongLong:
1411 case BuiltinType::Int128:
1412 case BuiltinType::Float:
1413 case BuiltinType::Double:
1414 case BuiltinType::LongDouble:
1415 case BuiltinType::NullPtr:
1416 case BuiltinType::Overload:
John McCall864c0412011-04-26 20:42:42 +00001417 case BuiltinType::BoundMember:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001418 case BuiltinType::Dependent:
John McCall1de4d4e2011-04-07 08:22:57 +00001419 case BuiltinType::UnknownAny:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001420 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001421
Ted Kremenekc4174cc2010-02-18 18:52:18 +00001422 case BuiltinType::ObjCId:
1423 VisitType = Context.getObjCIdType();
1424 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001425
1426 case BuiltinType::ObjCClass:
1427 VisitType = Context.getObjCClassType();
1428 break;
1429
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001430 case BuiltinType::ObjCSel:
1431 VisitType = Context.getObjCSelType();
1432 break;
1433 }
1434
1435 if (!VisitType.isNull()) {
1436 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001437 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001438 TU));
1439 }
1440
1441 return false;
1442}
1443
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001444bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
Richard Smith162e1c12011-04-15 14:24:37 +00001445 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001446}
1447
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001448bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1449 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1450}
1451
1452bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1453 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1454}
1455
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001456bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Chandler Carruth960d13d2011-05-01 09:53:37 +00001457 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001458}
1459
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001460bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1461 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1462 return true;
1463
John McCallc12c5bb2010-05-15 11:32:37 +00001464 return false;
1465}
1466
1467bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1468 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1469 return true;
1470
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001471 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1472 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1473 TU)))
1474 return true;
1475 }
1476
1477 return false;
1478}
1479
1480bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCallc12c5bb2010-05-15 11:32:37 +00001481 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001482}
1483
Abramo Bagnara075f8f12010-12-10 16:29:40 +00001484bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1485 return Visit(TL.getInnerLoc());
1486}
1487
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001488bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1489 return Visit(TL.getPointeeLoc());
1490}
1491
1492bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1493 return Visit(TL.getPointeeLoc());
1494}
1495
1496bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1497 return Visit(TL.getPointeeLoc());
1498}
1499
1500bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001501 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001502}
1503
1504bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001505 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001506}
1507
Douglas Gregor01829d32010-08-31 14:41:23 +00001508bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1509 bool SkipResultType) {
1510 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001511 return true;
1512
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001513 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek5dbacb42010-04-07 00:27:13 +00001514 if (Decl *D = TL.getArg(I))
1515 if (Visit(MakeCXCursor(D, TU)))
1516 return true;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001517
1518 return false;
1519}
1520
1521bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1522 if (Visit(TL.getElementLoc()))
1523 return true;
1524
1525 if (Expr *Size = TL.getSizeExpr())
1526 return Visit(MakeCXCursor(Size, StmtParent, TU));
1527
1528 return false;
1529}
1530
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001531bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1532 TemplateSpecializationTypeLoc TL) {
Douglas Gregor0b36e612010-08-31 20:37:03 +00001533 // Visit the template name.
1534 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1535 TL.getTemplateNameLoc()))
1536 return true;
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001537
1538 // Visit the template arguments.
1539 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1540 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1541 return true;
1542
1543 return false;
1544}
1545
Douglas Gregor2332c112010-01-21 20:48:56 +00001546bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1547 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1548}
1549
1550bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1551 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1552 return Visit(TSInfo->getTypeLoc());
1553
1554 return false;
1555}
1556
Sean Huntca63c202011-05-24 22:41:36 +00001557bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1558 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1559 return Visit(TSInfo->getTypeLoc());
1560
1561 return false;
1562}
1563
Douglas Gregor2494dd02011-03-01 01:34:45 +00001564bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1565 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1566 return true;
1567
1568 return false;
1569}
1570
Douglas Gregor94fdffa2011-03-01 20:11:18 +00001571bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1572 DependentTemplateSpecializationTypeLoc TL) {
1573 // Visit the nested-name-specifier, if there is one.
1574 if (TL.getQualifierLoc() &&
1575 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1576 return true;
1577
1578 // Visit the template arguments.
1579 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1580 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1581 return true;
1582
1583 return false;
1584}
1585
Douglas Gregor9e876872011-03-01 18:12:44 +00001586bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1587 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1588 return true;
1589
1590 return Visit(TL.getNamedTypeLoc());
1591}
1592
Douglas Gregor7536dd52010-12-20 02:24:11 +00001593bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1594 return Visit(TL.getPatternLoc());
1595}
1596
Ted Kremenek3064ef92010-08-27 21:34:58 +00001597bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001598 // Visit the nested-name-specifier, if present.
1599 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1600 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1601 return true;
1602
Ted Kremenek3064ef92010-08-27 21:34:58 +00001603 if (D->isDefinition()) {
1604 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1605 E = D->bases_end(); I != E; ++I) {
1606 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1607 return true;
1608 }
1609 }
1610
1611 return VisitTagDecl(D);
1612}
1613
Ted Kremenek09dfa372010-02-18 05:46:33 +00001614bool CursorVisitor::VisitAttributes(Decl *D) {
Sean Huntcf807c42010-08-18 23:23:40 +00001615 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1616 i != e; ++i)
1617 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek09dfa372010-02-18 05:46:33 +00001618 return true;
1619
1620 return false;
1621}
1622
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001623//===----------------------------------------------------------------------===//
1624// Data-recursive visitor methods.
1625//===----------------------------------------------------------------------===//
1626
Ted Kremenek28a71942010-11-13 00:36:47 +00001627namespace {
Ted Kremenek035dc412010-11-13 00:36:50 +00001628#define DEF_JOB(NAME, DATA, KIND)\
1629class NAME : public VisitorJob {\
1630public:\
1631 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1632 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenekf64d8032010-11-18 00:02:32 +00001633 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek035dc412010-11-13 00:36:50 +00001634};
1635
1636DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1637DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001638DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001639DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek60608ec2010-11-17 00:50:47 +00001640DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1641 ExplicitTemplateArgsVisitKind)
Douglas Gregor94d96292011-01-19 20:34:17 +00001642DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001643#undef DEF_JOB
1644
1645class DeclVisit : public VisitorJob {
1646public:
1647 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1648 VisitorJob(parent, VisitorJob::DeclVisitKind,
1649 d, isFirst ? (void*) 1 : (void*) 0) {}
1650 static bool classof(const VisitorJob *VJ) {
Ted Kremenek82f3c502010-11-15 22:23:26 +00001651 return VJ->getKind() == DeclVisitKind;
Ted Kremenek035dc412010-11-13 00:36:50 +00001652 }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001653 Decl *get() const { return static_cast<Decl*>(data[0]); }
1654 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek035dc412010-11-13 00:36:50 +00001655};
Ted Kremenek035dc412010-11-13 00:36:50 +00001656class TypeLocVisit : public VisitorJob {
1657public:
1658 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1659 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1660 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1661
1662 static bool classof(const VisitorJob *VJ) {
1663 return VJ->getKind() == TypeLocVisitKind;
1664 }
1665
Ted Kremenek82f3c502010-11-15 22:23:26 +00001666 TypeLoc get() const {
Ted Kremenekf64d8032010-11-18 00:02:32 +00001667 QualType T = QualType::getFromOpaquePtr(data[0]);
1668 return TypeLoc(T, data[1]);
Ted Kremenek035dc412010-11-13 00:36:50 +00001669 }
1670};
1671
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001672class LabelRefVisit : public VisitorJob {
1673public:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001674 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1675 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001676 labelLoc.getPtrEncoding()) {}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001677
1678 static bool classof(const VisitorJob *VJ) {
1679 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1680 }
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001681 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001682 SourceLocation getLoc() const {
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001683 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001684};
1685class NestedNameSpecifierVisit : public VisitorJob {
1686public:
1687 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1688 CXCursor parent)
1689 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001690 NS, R.getBegin().getPtrEncoding(),
1691 R.getEnd().getPtrEncoding()) {}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001692 static bool classof(const VisitorJob *VJ) {
1693 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1694 }
1695 NestedNameSpecifier *get() const {
1696 return static_cast<NestedNameSpecifier*>(data[0]);
1697 }
1698 SourceRange getSourceRange() const {
1699 SourceLocation A =
1700 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1701 SourceLocation B =
1702 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1703 return SourceRange(A, B);
1704 }
1705};
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001706
1707class NestedNameSpecifierLocVisit : public VisitorJob {
1708public:
1709 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1710 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1711 Qualifier.getNestedNameSpecifier(),
1712 Qualifier.getOpaqueData()) { }
1713
1714 static bool classof(const VisitorJob *VJ) {
1715 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1716 }
1717
1718 NestedNameSpecifierLoc get() const {
1719 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1720 data[1]);
1721 }
1722};
1723
Ted Kremenekf64d8032010-11-18 00:02:32 +00001724class DeclarationNameInfoVisit : public VisitorJob {
1725public:
1726 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1727 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1728 static bool classof(const VisitorJob *VJ) {
1729 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1730 }
1731 DeclarationNameInfo get() const {
1732 Stmt *S = static_cast<Stmt*>(data[0]);
1733 switch (S->getStmtClass()) {
1734 default:
1735 llvm_unreachable("Unhandled Stmt");
1736 case Stmt::CXXDependentScopeMemberExprClass:
1737 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1738 case Stmt::DependentScopeDeclRefExprClass:
1739 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1740 }
1741 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001742};
Ted Kremenekcdba6592010-11-18 00:42:18 +00001743class MemberRefVisit : public VisitorJob {
1744public:
1745 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1746 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001747 L.getPtrEncoding()) {}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001748 static bool classof(const VisitorJob *VJ) {
1749 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1750 }
1751 FieldDecl *get() const {
1752 return static_cast<FieldDecl*>(data[0]);
1753 }
1754 SourceLocation getLoc() const {
1755 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1756 }
1757};
Ted Kremenek28a71942010-11-13 00:36:47 +00001758class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1759 VisitorWorkList &WL;
1760 CXCursor Parent;
1761public:
1762 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1763 : WL(wl), Parent(parent) {}
1764
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001765 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001766 void VisitBlockExpr(BlockExpr *B);
Ted Kremenek28a71942010-11-13 00:36:47 +00001767 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenek083c7e22010-11-13 05:38:03 +00001768 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001769 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001770 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001771 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001772 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001773 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001774 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001775 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001776 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek55b933a2010-11-17 00:50:36 +00001777 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001778 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001779 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek035dc412010-11-13 00:36:50 +00001780 void VisitDeclStmt(DeclStmt *S);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001781 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001782 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001783 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1784 void VisitForStmt(ForStmt *FS);
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001785 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenek28a71942010-11-13 00:36:47 +00001786 void VisitIfStmt(IfStmt *If);
1787 void VisitInitListExpr(InitListExpr *IE);
1788 void VisitMemberExpr(MemberExpr *M);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001789 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001790 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001791 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1792 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00001793 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001794 void VisitStmt(Stmt *S);
1795 void VisitSwitchStmt(SwitchStmt *S);
1796 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek2939b6f2010-11-17 00:50:50 +00001797 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet6ad6f282010-12-07 00:08:36 +00001798 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
John Wiegley21ff2e52011-04-28 00:16:57 +00001799 void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
John Wiegley55262202011-04-25 06:54:41 +00001800 void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001801 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenek9d3bf792010-11-17 00:50:43 +00001802 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor94d96292011-01-19 20:34:17 +00001803 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregoree8aff02011-01-04 17:33:58 +00001804
Ted Kremenek28a71942010-11-13 00:36:47 +00001805private:
Ted Kremenekf64d8032010-11-18 00:02:32 +00001806 void AddDeclarationNameInfo(Stmt *S);
1807 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001808 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek60608ec2010-11-17 00:50:47 +00001809 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001810 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenek28a71942010-11-13 00:36:47 +00001811 void AddStmt(Stmt *S);
Ted Kremenek035dc412010-11-13 00:36:50 +00001812 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenek28a71942010-11-13 00:36:47 +00001813 void AddTypeLoc(TypeSourceInfo *TI);
1814 void EnqueueChildren(Stmt *S);
1815};
1816} // end anonyous namespace
1817
Ted Kremenekf64d8032010-11-18 00:02:32 +00001818void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1819 // 'S' should always be non-null, since it comes from the
1820 // statement we are visiting.
1821 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1822}
1823void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1824 SourceRange R) {
1825 if (N)
1826 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1827}
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001828
1829void
1830EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1831 if (Qualifier)
1832 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1833}
1834
Ted Kremenek28a71942010-11-13 00:36:47 +00001835void EnqueueVisitor::AddStmt(Stmt *S) {
1836 if (S)
1837 WL.push_back(StmtVisit(S, Parent));
1838}
Ted Kremenek035dc412010-11-13 00:36:50 +00001839void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001840 if (D)
Ted Kremenek035dc412010-11-13 00:36:50 +00001841 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenek28a71942010-11-13 00:36:47 +00001842}
Ted Kremenek60608ec2010-11-17 00:50:47 +00001843void EnqueueVisitor::
1844 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1845 if (A)
1846 WL.push_back(ExplicitTemplateArgsVisit(
1847 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1848}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001849void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1850 if (D)
1851 WL.push_back(MemberRefVisit(D, L, Parent));
1852}
Ted Kremenek28a71942010-11-13 00:36:47 +00001853void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1854 if (TI)
1855 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1856 }
1857void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremeneka6b70432010-11-12 21:34:09 +00001858 unsigned size = WL.size();
John McCall7502c1d2011-02-13 04:07:26 +00001859 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001860 AddStmt(*Child);
Ted Kremeneka6b70432010-11-12 21:34:09 +00001861 }
1862 if (size == WL.size())
1863 return;
1864 // Now reverse the entries we just added. This will match the DFS
1865 // ordering performed by the worklist.
1866 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1867 std::reverse(I, E);
1868}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001869void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1870 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1871}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001872void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1873 AddDecl(B->getBlockDecl());
1874}
Ted Kremenek28a71942010-11-13 00:36:47 +00001875void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1876 EnqueueChildren(E);
1877 AddTypeLoc(E->getTypeSourceInfo());
1878}
Ted Kremenek083c7e22010-11-13 05:38:03 +00001879void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1880 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1881 E = S->body_rend(); I != E; ++I) {
1882 AddStmt(*I);
1883 }
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001884}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001885void EnqueueVisitor::
1886VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1887 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1888 AddDeclarationNameInfo(E);
Douglas Gregor7c3179c2011-02-28 18:50:33 +00001889 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1890 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001891 if (!E->isImplicitAccess())
1892 AddStmt(E->getBase());
1893}
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001894void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1895 // Enqueue the initializer or constructor arguments.
1896 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1897 AddStmt(E->getConstructorArg(I-1));
1898 // Enqueue the array size, if any.
1899 AddStmt(E->getArraySize());
1900 // Enqueue the allocated type.
1901 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1902 // Enqueue the placement arguments.
1903 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1904 AddStmt(E->getPlacementArg(I-1));
1905}
Ted Kremenek28a71942010-11-13 00:36:47 +00001906void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenek8b8d8c92010-11-13 05:55:56 +00001907 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1908 AddStmt(CE->getArg(I-1));
Ted Kremenek28a71942010-11-13 00:36:47 +00001909 AddStmt(CE->getCallee());
1910 AddStmt(CE->getArg(0));
1911}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001912void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1913 // Visit the name of the type being destroyed.
1914 AddTypeLoc(E->getDestroyedTypeInfo());
1915 // Visit the scope type that looks disturbingly like the nested-name-specifier
1916 // but isn't.
1917 AddTypeLoc(E->getScopeTypeInfo());
1918 // Visit the nested-name-specifier.
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001919 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1920 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001921 // Visit base expression.
1922 AddStmt(E->getBase());
1923}
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001924void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1925 AddTypeLoc(E->getTypeSourceInfo());
1926}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001927void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1928 EnqueueChildren(E);
1929 AddTypeLoc(E->getTypeSourceInfo());
1930}
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001931void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1932 EnqueueChildren(E);
1933 if (E->isTypeOperand())
1934 AddTypeLoc(E->getTypeOperandSourceInfo());
1935}
Ted Kremenek55b933a2010-11-17 00:50:36 +00001936
1937void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1938 *E) {
1939 EnqueueChildren(E);
1940 AddTypeLoc(E->getTypeSourceInfo());
1941}
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001942void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1943 EnqueueChildren(E);
1944 if (E->isTypeOperand())
1945 AddTypeLoc(E->getTypeOperandSourceInfo());
1946}
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001947void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00001948 if (DR->hasExplicitTemplateArgs()) {
1949 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1950 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001951 WL.push_back(DeclRefExprParts(DR, Parent));
1952}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001953void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1954 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1955 AddDeclarationNameInfo(E);
Douglas Gregor00cf3cc2011-02-25 20:49:16 +00001956 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenekf64d8032010-11-18 00:02:32 +00001957}
Ted Kremenek035dc412010-11-13 00:36:50 +00001958void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1959 unsigned size = WL.size();
1960 bool isFirst = true;
1961 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1962 D != DEnd; ++D) {
1963 AddDecl(*D, isFirst);
1964 isFirst = false;
1965 }
1966 if (size == WL.size())
1967 return;
1968 // Now reverse the entries we just added. This will match the DFS
1969 // ordering performed by the worklist.
1970 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1971 std::reverse(I, E);
1972}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001973void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1974 AddStmt(E->getInit());
1975 typedef DesignatedInitExpr::Designator Designator;
1976 for (DesignatedInitExpr::reverse_designators_iterator
1977 D = E->designators_rbegin(), DEnd = E->designators_rend();
1978 D != DEnd; ++D) {
1979 if (D->isFieldDesignator()) {
1980 if (FieldDecl *Field = D->getField())
1981 AddMemberRef(Field, D->getFieldLoc());
1982 continue;
1983 }
1984 if (D->isArrayDesignator()) {
1985 AddStmt(E->getArrayIndex(*D));
1986 continue;
1987 }
1988 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1989 AddStmt(E->getArrayRangeEnd(*D));
1990 AddStmt(E->getArrayRangeStart(*D));
1991 }
1992}
Ted Kremenek28a71942010-11-13 00:36:47 +00001993void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1994 EnqueueChildren(E);
1995 AddTypeLoc(E->getTypeInfoAsWritten());
1996}
1997void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1998 AddStmt(FS->getBody());
1999 AddStmt(FS->getInc());
2000 AddStmt(FS->getCond());
2001 AddDecl(FS->getConditionVariable());
2002 AddStmt(FS->getInit());
2003}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002004void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
2005 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2006}
Ted Kremenek28a71942010-11-13 00:36:47 +00002007void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
2008 AddStmt(If->getElse());
2009 AddStmt(If->getThen());
2010 AddStmt(If->getCond());
2011 AddDecl(If->getConditionVariable());
2012}
2013void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
2014 // We care about the syntactic form of the initializer list, only.
2015 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2016 IE = Syntactic;
2017 EnqueueChildren(IE);
2018}
2019void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor89629a72010-11-17 17:15:08 +00002020 WL.push_back(MemberExprParts(M, Parent));
2021
2022 // If the base of the member access expression is an implicit 'this', don't
2023 // visit it.
2024 // FIXME: If we ever want to show these implicit accesses, this will be
2025 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor75e85042011-03-02 21:06:53 +00002026 if (!M->isImplicitAccess())
2027 AddStmt(M->getBase());
Ted Kremenek28a71942010-11-13 00:36:47 +00002028}
Ted Kremenek73d15c42010-11-13 01:09:29 +00002029void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2030 AddTypeLoc(E->getEncodedTypeSourceInfo());
2031}
Ted Kremenek28a71942010-11-13 00:36:47 +00002032void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2033 EnqueueChildren(M);
2034 AddTypeLoc(M->getClassReceiverTypeInfo());
2035}
Ted Kremenekcdba6592010-11-18 00:42:18 +00002036void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2037 // Visit the components of the offsetof expression.
2038 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2039 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2040 const OffsetOfNode &Node = E->getComponent(I-1);
2041 switch (Node.getKind()) {
2042 case OffsetOfNode::Array:
2043 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2044 break;
2045 case OffsetOfNode::Field:
Abramo Bagnara06dec892011-03-12 09:45:03 +00002046 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenekcdba6592010-11-18 00:42:18 +00002047 break;
2048 case OffsetOfNode::Identifier:
2049 case OffsetOfNode::Base:
2050 continue;
2051 }
2052 }
2053 // Visit the type into which we're computing the offset.
2054 AddTypeLoc(E->getTypeSourceInfo());
2055}
Ted Kremenek28a71942010-11-13 00:36:47 +00002056void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00002057 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenek60458782010-11-12 21:34:16 +00002058 WL.push_back(OverloadExprParts(E, Parent));
2059}
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00002060void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2061 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00002062 EnqueueChildren(E);
2063 if (E->isArgumentType())
2064 AddTypeLoc(E->getArgumentTypeInfo());
2065}
Ted Kremenek28a71942010-11-13 00:36:47 +00002066void EnqueueVisitor::VisitStmt(Stmt *S) {
2067 EnqueueChildren(S);
2068}
2069void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2070 AddStmt(S->getBody());
2071 AddStmt(S->getCond());
2072 AddDecl(S->getConditionVariable());
2073}
Ted Kremenekfafa75a2010-11-17 00:50:39 +00002074
Ted Kremenek28a71942010-11-13 00:36:47 +00002075void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2076 AddStmt(W->getBody());
2077 AddStmt(W->getCond());
2078 AddDecl(W->getConditionVariable());
2079}
John Wiegley21ff2e52011-04-28 00:16:57 +00002080
Ted Kremenek2939b6f2010-11-17 00:50:50 +00002081void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2082 AddTypeLoc(E->getQueriedTypeSourceInfo());
2083}
Francois Pichet6ad6f282010-12-07 00:08:36 +00002084
2085void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet6ad6f282010-12-07 00:08:36 +00002086 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichet0a03a3f2010-12-08 09:11:05 +00002087 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet6ad6f282010-12-07 00:08:36 +00002088}
2089
John Wiegley21ff2e52011-04-28 00:16:57 +00002090void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2091 AddTypeLoc(E->getQueriedTypeSourceInfo());
2092}
2093
John Wiegley55262202011-04-25 06:54:41 +00002094void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2095 EnqueueChildren(E);
2096}
2097
Ted Kremenek28a71942010-11-13 00:36:47 +00002098void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2099 VisitOverloadExpr(U);
2100 if (!U->isImplicitAccess())
2101 AddStmt(U->getBase());
2102}
Ted Kremenek9d3bf792010-11-17 00:50:43 +00002103void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2104 AddStmt(E->getSubExpr());
2105 AddTypeLoc(E->getWrittenTypeInfo());
2106}
Douglas Gregor94d96292011-01-19 20:34:17 +00002107void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2108 WL.push_back(SizeOfPackExprParts(E, Parent));
2109}
Ted Kremenek60458782010-11-12 21:34:16 +00002110
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002111void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenek28a71942010-11-13 00:36:47 +00002112 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002113}
2114
2115bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2116 if (RegionOfInterest.isValid()) {
2117 SourceRange Range = getRawCursorExtent(C);
2118 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2119 return false;
2120 }
2121 return true;
2122}
2123
2124bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2125 while (!WL.empty()) {
2126 // Dequeue the worklist item.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002127 VisitorJob LI = WL.back();
2128 WL.pop_back();
2129
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002130 // Set the Parent field, then back to its old value once we're done.
2131 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2132
2133 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00002134 case VisitorJob::DeclVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002135 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenekf1107452010-11-12 18:26:56 +00002136 if (!D)
2137 continue;
2138
2139 // For now, perform default visitation for Decls.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002140 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenekf1107452010-11-12 18:26:56 +00002141 return true;
2142
2143 continue;
2144 }
Ted Kremenek60608ec2010-11-17 00:50:47 +00002145 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2146 const ExplicitTemplateArgumentList *ArgList =
2147 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2148 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2149 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2150 Arg != ArgEnd; ++Arg) {
2151 if (VisitTemplateArgumentLoc(*Arg))
2152 return true;
2153 }
2154 continue;
2155 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002156 case VisitorJob::TypeLocVisitKind: {
2157 // Perform default visitation for TypeLocs.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002158 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002159 return true;
2160 continue;
2161 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002162 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002163 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremeneke7455012011-02-23 04:54:51 +00002164 if (LabelStmt *stmt = LS->getStmt()) {
2165 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2166 TU))) {
2167 return true;
2168 }
2169 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002170 continue;
2171 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002172
Ted Kremenekf64d8032010-11-18 00:02:32 +00002173 case VisitorJob::NestedNameSpecifierVisitKind: {
2174 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2175 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2176 return true;
2177 continue;
2178 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002179
2180 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2181 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2182 if (VisitNestedNameSpecifierLoc(V->get()))
2183 return true;
2184 continue;
2185 }
2186
Ted Kremenekf64d8032010-11-18 00:02:32 +00002187 case VisitorJob::DeclarationNameInfoVisitKind: {
2188 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2189 ->get()))
2190 return true;
2191 continue;
2192 }
Ted Kremenekcdba6592010-11-18 00:42:18 +00002193 case VisitorJob::MemberRefVisitKind: {
2194 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2195 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2196 return true;
2197 continue;
2198 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002199 case VisitorJob::StmtVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002200 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002201 if (!S)
2202 continue;
2203
Ted Kremenekf1107452010-11-12 18:26:56 +00002204 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002205 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenekcdba6592010-11-18 00:42:18 +00002206 if (!IsInRegionOfInterest(Cursor))
2207 continue;
2208 switch (Visitor(Cursor, Parent, ClientData)) {
2209 case CXChildVisit_Break: return true;
2210 case CXChildVisit_Continue: break;
2211 case CXChildVisit_Recurse:
2212 EnqueueWorkList(WL, S);
Ted Kremenek82f3c502010-11-15 22:23:26 +00002213 break;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002214 }
Ted Kremenek82f3c502010-11-15 22:23:26 +00002215 continue;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002216 }
2217 case VisitorJob::MemberExprPartsKind: {
2218 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002219 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002220
2221 // Visit the nested-name-specifier
Douglas Gregor40d96a62011-02-28 21:54:11 +00002222 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2223 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002224 return true;
2225
2226 // Visit the declaration name.
2227 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2228 return true;
2229
2230 // Visit the explicitly-specified template arguments, if any.
2231 if (M->hasExplicitTemplateArgs()) {
2232 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2233 *ArgEnd = Arg + M->getNumTemplateArgs();
2234 Arg != ArgEnd; ++Arg) {
2235 if (VisitTemplateArgumentLoc(*Arg))
2236 return true;
2237 }
2238 }
2239 continue;
2240 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002241 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002242 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002243 // Visit nested-name-specifier, if present.
Douglas Gregor40d96a62011-02-28 21:54:11 +00002244 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2245 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002246 return true;
2247 // Visit declaration name.
2248 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2249 return true;
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002250 continue;
2251 }
Ted Kremenek60458782010-11-12 21:34:16 +00002252 case VisitorJob::OverloadExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002253 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenek60458782010-11-12 21:34:16 +00002254 // Visit the nested-name-specifier.
Douglas Gregor4c9be892011-02-28 20:01:57 +00002255 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2256 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek60458782010-11-12 21:34:16 +00002257 return true;
2258 // Visit the declaration name.
2259 if (VisitDeclarationNameInfo(O->getNameInfo()))
2260 return true;
2261 // Visit the overloaded declaration reference.
2262 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2263 return true;
Ted Kremenek60458782010-11-12 21:34:16 +00002264 continue;
2265 }
Douglas Gregor94d96292011-01-19 20:34:17 +00002266 case VisitorJob::SizeOfPackExprPartsKind: {
2267 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2268 NamedDecl *Pack = E->getPack();
2269 if (isa<TemplateTypeParmDecl>(Pack)) {
2270 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2271 E->getPackLoc(), TU)))
2272 return true;
2273
2274 continue;
2275 }
2276
2277 if (isa<TemplateTemplateParmDecl>(Pack)) {
2278 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2279 E->getPackLoc(), TU)))
2280 return true;
2281
2282 continue;
2283 }
2284
2285 // Non-type template parameter packs and function parameter packs are
2286 // treated like DeclRefExpr cursors.
2287 continue;
2288 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002289 }
2290 }
2291 return false;
2292}
2293
Ted Kremenekcdba6592010-11-18 00:42:18 +00002294bool CursorVisitor::Visit(Stmt *S) {
Ted Kremenekd1ded662010-11-15 23:31:32 +00002295 VisitorWorkList *WL = 0;
2296 if (!WorkListFreeList.empty()) {
2297 WL = WorkListFreeList.back();
2298 WL->clear();
2299 WorkListFreeList.pop_back();
2300 }
2301 else {
2302 WL = new VisitorWorkList();
2303 WorkListCache.push_back(WL);
2304 }
2305 EnqueueWorkList(*WL, S);
2306 bool result = RunVisitorWorkList(*WL);
2307 WorkListFreeList.push_back(WL);
2308 return result;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002309}
2310
2311//===----------------------------------------------------------------------===//
2312// Misc. API hooks.
2313//===----------------------------------------------------------------------===//
2314
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002315static llvm::sys::Mutex EnableMultithreadingMutex;
2316static bool EnabledMultithreading;
2317
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002318extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002319CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2320 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002321 // Disable pretty stack trace functionality, which will otherwise be a very
2322 // poor citizen of the world and set up all sorts of signal handlers.
2323 llvm::DisablePrettyStackTrace = true;
2324
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002325 // We use crash recovery to make some of our APIs more reliable, implicitly
2326 // enable it.
2327 llvm::CrashRecoveryContext::Enable();
2328
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002329 // Enable support for multithreading in LLVM.
2330 {
2331 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2332 if (!EnabledMultithreading) {
2333 llvm::llvm_start_multithreaded();
2334 EnabledMultithreading = true;
2335 }
2336 }
2337
Douglas Gregora030b7c2010-01-22 20:35:53 +00002338 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002339 if (excludeDeclarationsFromPCH)
2340 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002341 if (displayDiagnostics)
2342 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002343 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002344}
2345
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002346void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002347 if (CIdx)
2348 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002349}
2350
Ted Kremenekd2427dd2011-03-18 23:05:39 +00002351void clang_toggleCrashRecovery(unsigned isEnabled) {
2352 if (isEnabled)
2353 llvm::CrashRecoveryContext::Enable();
2354 else
2355 llvm::CrashRecoveryContext::Disable();
2356}
2357
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002358CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002359 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002360 if (!CIdx)
2361 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002362
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002363 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002364 FileSystemOptions FileSystemOpts;
2365 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002366
Douglas Gregor28019772010-04-05 23:52:57 +00002367 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremeneka60ed472010-11-16 08:15:36 +00002368 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002369 CXXIdx->getOnlyLocalDecls(),
2370 0, 0, true);
Ted Kremeneka60ed472010-11-16 08:15:36 +00002371 return MakeCXTranslationUnit(TU);
Steve Naroff600866c2009-08-27 19:51:58 +00002372}
2373
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002374unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002375 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002376 CXTranslationUnit_CacheCompletionResults |
2377 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002378}
2379
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002380CXTranslationUnit
2381clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2382 const char *source_filename,
2383 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002384 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002385 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002386 struct CXUnsavedFile *unsaved_files) {
Douglas Gregordca8ee82011-05-06 16:33:08 +00002387 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord |
2388 CXTranslationUnit_NestedMacroInstantiations;
Douglas Gregor5a430212010-07-21 18:52:53 +00002389 return clang_parseTranslationUnit(CIdx, source_filename,
2390 command_line_args, num_command_line_args,
2391 unsaved_files, num_unsaved_files,
Douglas Gregordca8ee82011-05-06 16:33:08 +00002392 Options);
Douglas Gregor5a430212010-07-21 18:52:53 +00002393}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002394
2395struct ParseTranslationUnitInfo {
2396 CXIndex CIdx;
2397 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002398 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002399 int num_command_line_args;
2400 struct CXUnsavedFile *unsaved_files;
2401 unsigned num_unsaved_files;
2402 unsigned options;
2403 CXTranslationUnit result;
2404};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002405static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002406 ParseTranslationUnitInfo *PTUI =
2407 static_cast<ParseTranslationUnitInfo*>(UserData);
2408 CXIndex CIdx = PTUI->CIdx;
2409 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002410 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002411 int num_command_line_args = PTUI->num_command_line_args;
2412 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2413 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2414 unsigned options = PTUI->options;
2415 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002416
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002417 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002418 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002419
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002420 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2421
Douglas Gregor44c181a2010-07-23 00:33:23 +00002422 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002423 bool CompleteTranslationUnit
2424 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002425 bool CacheCodeCompetionResults
2426 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002427 bool CXXPrecompilePreamble
2428 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2429 bool CXXChainedPCH
2430 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002431
Douglas Gregor5352ac02010-01-28 00:27:43 +00002432 // Configure the diagnostics.
2433 DiagnosticOptions DiagOpts;
Ted Kremenek25a11e12011-03-22 01:15:24 +00002434 llvm::IntrusiveRefCntPtr<Diagnostic>
2435 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2436 command_line_args));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002437
Ted Kremenek25a11e12011-03-22 01:15:24 +00002438 // Recover resources if we crash before exiting this function.
2439 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2440 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2441 DiagCleanup(Diags.getPtr());
2442
2443 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2444 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2445
2446 // Recover resources if we crash before exiting this function.
2447 llvm::CrashRecoveryContextCleanupRegistrar<
2448 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2449
Douglas Gregor4db64a42010-01-23 00:14:00 +00002450 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002451 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002452 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002453 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002454 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2455 Buffer));
Douglas Gregor4db64a42010-01-23 00:14:00 +00002456 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002457
Ted Kremenek25a11e12011-03-22 01:15:24 +00002458 llvm::OwningPtr<std::vector<const char *> >
2459 Args(new std::vector<const char*>());
2460
2461 // Recover resources if we crash before exiting this method.
2462 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2463 ArgsCleanup(Args.get());
2464
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002465 // Since the Clang C library is primarily used by batch tools dealing with
2466 // (often very broken) source code, where spell-checking can have a
2467 // significant negative impact on performance (particularly when
2468 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002469 // Only do this if we haven't found a spell-checking-related argument.
2470 bool FoundSpellCheckingArgument = false;
2471 for (int I = 0; I != num_command_line_args; ++I) {
2472 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2473 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2474 FoundSpellCheckingArgument = true;
2475 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002476 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002477 }
2478 if (!FoundSpellCheckingArgument)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002479 Args->push_back("-fno-spell-checking");
Douglas Gregorb10daed2010-10-11 16:52:23 +00002480
Ted Kremenek25a11e12011-03-22 01:15:24 +00002481 Args->insert(Args->end(), command_line_args,
2482 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002483
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002484 // The 'source_filename' argument is optional. If the caller does not
2485 // specify it then it is assumed that the source file is specified
2486 // in the actual argument list.
2487 // Put the source file after command_line_args otherwise if '-x' flag is
2488 // present it will be unused.
2489 if (source_filename)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002490 Args->push_back(source_filename);
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002491
Douglas Gregor44c181a2010-07-23 00:33:23 +00002492 // Do we need the detailed preprocessing record?
Douglas Gregordca8ee82011-05-06 16:33:08 +00002493 bool NestedMacroInstantiations = false;
Douglas Gregor44c181a2010-07-23 00:33:23 +00002494 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek25a11e12011-03-22 01:15:24 +00002495 Args->push_back("-Xclang");
2496 Args->push_back("-detailed-preprocessing-record");
Douglas Gregordca8ee82011-05-06 16:33:08 +00002497 NestedMacroInstantiations
2498 = (options & CXTranslationUnit_NestedMacroInstantiations);
Douglas Gregor44c181a2010-07-23 00:33:23 +00002499 }
2500
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002501 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002502 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek4ee99262011-03-22 20:16:19 +00002503 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2504 /* vector::data() not portable */,
2505 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002506 Diags,
2507 CXXIdx->getClangResourcesPath(),
2508 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002509 /*CaptureDiagnostics=*/true,
Ted Kremenek4ee99262011-03-22 20:16:19 +00002510 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek25a11e12011-03-22 01:15:24 +00002511 RemappedFiles->size(),
Argyrios Kyrtzidis299a4a92011-03-08 23:35:24 +00002512 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002513 PrecompilePreamble,
2514 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002515 CacheCodeCompetionResults,
2516 CXXPrecompilePreamble,
Douglas Gregordca8ee82011-05-06 16:33:08 +00002517 CXXChainedPCH,
2518 NestedMacroInstantiations));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002519
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002520 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002521 // Make sure to check that 'Unit' is non-NULL.
2522 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2523 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2524 DEnd = Unit->stored_diag_end();
2525 D != DEnd; ++D) {
2526 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2527 CXString Msg = clang_formatDiagnostic(&Diag,
2528 clang_defaultDiagnosticDisplayOptions());
2529 fprintf(stderr, "%s\n", clang_getCString(Msg));
2530 clang_disposeString(Msg);
2531 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002532#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002533 // On Windows, force a flush, since there may be multiple copies of
2534 // stderr and stdout in the file system, all with different buffers
2535 // but writing to the same device.
2536 fflush(stderr);
2537#endif
2538 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002539 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002540
Ted Kremeneka60ed472010-11-16 08:15:36 +00002541 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002542}
2543CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2544 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002545 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002546 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002547 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002548 unsigned num_unsaved_files,
2549 unsigned options) {
2550 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002551 num_command_line_args, unsaved_files,
2552 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002553 llvm::CrashRecoveryContext CRC;
2554
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002555 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002556 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2557 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2558 fprintf(stderr, " 'command_line_args' : [");
2559 for (int i = 0; i != num_command_line_args; ++i) {
2560 if (i)
2561 fprintf(stderr, ", ");
2562 fprintf(stderr, "'%s'", command_line_args[i]);
2563 }
2564 fprintf(stderr, "],\n");
2565 fprintf(stderr, " 'unsaved_files' : [");
2566 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2567 if (i)
2568 fprintf(stderr, ", ");
2569 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2570 unsaved_files[i].Length);
2571 }
2572 fprintf(stderr, "],\n");
2573 fprintf(stderr, " 'options' : %d,\n", options);
2574 fprintf(stderr, "}\n");
2575
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002576 return 0;
Douglas Gregor6df78732011-05-05 20:27:22 +00002577 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2578 PrintLibclangResourceUsage(PTUI.result);
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002579 }
Douglas Gregor6df78732011-05-05 20:27:22 +00002580
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002581 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002582}
2583
Douglas Gregor19998442010-08-13 15:35:05 +00002584unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2585 return CXSaveTranslationUnit_None;
2586}
2587
2588int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2589 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002590 if (!TU)
2591 return 1;
2592
Douglas Gregor6df78732011-05-05 20:27:22 +00002593 int result = static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
2594 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2595 PrintLibclangResourceUsage(TU);
2596 return result;
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002597}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002598
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002599void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002600 if (CTUnit) {
2601 // If the translation unit has been marked as unsafe to free, just discard
2602 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002603 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002604 return;
2605
Ted Kremeneka60ed472010-11-16 08:15:36 +00002606 delete static_cast<ASTUnit *>(CTUnit->TUData);
2607 disposeCXStringPool(CTUnit->StringPool);
2608 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002609 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002610}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002611
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002612unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2613 return CXReparse_None;
2614}
2615
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002616struct ReparseTranslationUnitInfo {
2617 CXTranslationUnit TU;
2618 unsigned num_unsaved_files;
2619 struct CXUnsavedFile *unsaved_files;
2620 unsigned options;
2621 int result;
2622};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002623
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002624static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002625 ReparseTranslationUnitInfo *RTUI =
2626 static_cast<ReparseTranslationUnitInfo*>(UserData);
2627 CXTranslationUnit TU = RTUI->TU;
2628 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2629 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2630 unsigned options = RTUI->options;
2631 (void) options;
2632 RTUI->result = 1;
2633
Douglas Gregorabc563f2010-07-19 21:46:24 +00002634 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002635 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002636
Ted Kremeneka60ed472010-11-16 08:15:36 +00002637 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002638 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002639
Ted Kremenek25a11e12011-03-22 01:15:24 +00002640 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2641 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2642
2643 // Recover resources if we crash before exiting this function.
2644 llvm::CrashRecoveryContextCleanupRegistrar<
2645 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2646
Douglas Gregorabc563f2010-07-19 21:46:24 +00002647 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2648 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2649 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002650 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002651 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2652 Buffer));
Douglas Gregorabc563f2010-07-19 21:46:24 +00002653 }
2654
Ted Kremenek4ee99262011-03-22 20:16:19 +00002655 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2656 RemappedFiles->size()))
Douglas Gregor593b0c12010-09-23 18:47:53 +00002657 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002658}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002659
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002660int clang_reparseTranslationUnit(CXTranslationUnit TU,
2661 unsigned num_unsaved_files,
2662 struct CXUnsavedFile *unsaved_files,
2663 unsigned options) {
2664 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2665 options, 0 };
2666 llvm::CrashRecoveryContext CRC;
2667
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002668 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002669 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002670 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002671 return 1;
Douglas Gregor6df78732011-05-05 20:27:22 +00002672 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2673 PrintLibclangResourceUsage(TU);
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002674
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002675 return RTUI.result;
2676}
2677
Douglas Gregordf95a132010-08-09 20:45:32 +00002678
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002679CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002680 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002681 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002682
Ted Kremeneka60ed472010-11-16 08:15:36 +00002683 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002684 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002685}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002686
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002687CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002688 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002689 return Result;
2690}
2691
Ted Kremenekfb480492010-01-13 21:46:36 +00002692} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002693
Ted Kremenekfb480492010-01-13 21:46:36 +00002694//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002695// CXSourceLocation and CXSourceRange Operations.
2696//===----------------------------------------------------------------------===//
2697
Douglas Gregorb9790342010-01-22 21:44:22 +00002698extern "C" {
2699CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002700 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002701 return Result;
2702}
2703
2704unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002705 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2706 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2707 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002708}
2709
2710CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2711 CXFile file,
2712 unsigned line,
2713 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002714 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002715 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002716
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002717 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002718 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002719 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002720 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002721 = CXXUnit->getSourceManager().getLocation(File, line, column);
2722 if (SLoc.isInvalid()) {
2723 if (Logging)
2724 llvm::errs() << "clang_getLocation(\"" << File->getName()
2725 << "\", " << line << ", " << column << ") = invalid\n";
2726 return clang_getNullLocation();
2727 }
2728
2729 if (Logging)
2730 llvm::errs() << "clang_getLocation(\"" << File->getName()
2731 << "\", " << line << ", " << column << ") = "
2732 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002733
2734 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2735}
2736
2737CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2738 CXFile file,
2739 unsigned offset) {
2740 if (!tu || !file)
2741 return clang_getNullLocation();
2742
Ted Kremeneka60ed472010-11-16 08:15:36 +00002743 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002744 SourceLocation Start
2745 = CXXUnit->getSourceManager().getLocation(
2746 static_cast<const FileEntry *>(file),
2747 1, 1);
2748 if (Start.isInvalid()) return clang_getNullLocation();
2749
2750 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2751
2752 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002753
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002754 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002755}
2756
Douglas Gregor5352ac02010-01-28 00:27:43 +00002757CXSourceRange clang_getNullRange() {
2758 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2759 return Result;
2760}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002761
Douglas Gregor5352ac02010-01-28 00:27:43 +00002762CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2763 if (begin.ptr_data[0] != end.ptr_data[0] ||
2764 begin.ptr_data[1] != end.ptr_data[1])
2765 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002766
2767 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002768 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002769 return Result;
2770}
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002771} // end: extern "C"
Douglas Gregorb9790342010-01-22 21:44:22 +00002772
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002773static void createNullLocation(CXFile *file, unsigned *line,
2774 unsigned *column, unsigned *offset) {
2775 if (file)
2776 *file = 0;
2777 if (line)
2778 *line = 0;
2779 if (column)
2780 *column = 0;
2781 if (offset)
2782 *offset = 0;
2783 return;
2784}
2785
2786extern "C" {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002787void clang_getInstantiationLocation(CXSourceLocation location,
2788 CXFile *file,
2789 unsigned *line,
2790 unsigned *column,
2791 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002792 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2793
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002794 if (!location.ptr_data[0] || Loc.isInvalid()) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002795 createNullLocation(file, line, column, offset);
Douglas Gregor46766dc2010-01-26 19:19:08 +00002796 return;
2797 }
2798
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002799 const SourceManager &SM =
2800 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002801 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002802
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002803 // Check that the FileID is invalid on the instantiation location.
2804 // This can manifest in invalid code.
2805 FileID fileID = SM.getFileID(InstLoc);
Douglas Gregore23ac652011-04-20 00:21:03 +00002806 bool Invalid = false;
2807 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
2808 if (!sloc.isFile() || Invalid) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002809 createNullLocation(file, line, column, offset);
2810 return;
2811 }
2812
Douglas Gregor1db19de2010-01-19 21:36:55 +00002813 if (file)
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002814 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002815 if (line)
2816 *line = SM.getInstantiationLineNumber(InstLoc);
2817 if (column)
2818 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002819 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002820 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002821}
2822
Douglas Gregora9b06d42010-11-09 06:24:54 +00002823void clang_getSpellingLocation(CXSourceLocation location,
2824 CXFile *file,
2825 unsigned *line,
2826 unsigned *column,
2827 unsigned *offset) {
2828 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2829
Argyrios Kyrtzidis5adc0512011-05-17 22:09:53 +00002830 if (!location.ptr_data[0] || Loc.isInvalid())
2831 return createNullLocation(file, line, column, offset);
Douglas Gregora9b06d42010-11-09 06:24:54 +00002832
2833 const SourceManager &SM =
2834 *static_cast<const SourceManager*>(location.ptr_data[0]);
2835 SourceLocation SpellLoc = Loc;
2836 if (SpellLoc.isMacroID()) {
2837 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2838 if (SimpleSpellingLoc.isFileID() &&
2839 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2840 SpellLoc = SimpleSpellingLoc;
2841 else
2842 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2843 }
2844
2845 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2846 FileID FID = LocInfo.first;
2847 unsigned FileOffset = LocInfo.second;
2848
Argyrios Kyrtzidis5adc0512011-05-17 22:09:53 +00002849 if (FID.isInvalid())
2850 return createNullLocation(file, line, column, offset);
2851
Douglas Gregora9b06d42010-11-09 06:24:54 +00002852 if (file)
2853 *file = (void *)SM.getFileEntryForID(FID);
2854 if (line)
2855 *line = SM.getLineNumber(FID, FileOffset);
2856 if (column)
2857 *column = SM.getColumnNumber(FID, FileOffset);
2858 if (offset)
2859 *offset = FileOffset;
2860}
2861
Douglas Gregor1db19de2010-01-19 21:36:55 +00002862CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002863 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002864 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002865 return Result;
2866}
2867
2868CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002869 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002870 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002871 return Result;
2872}
2873
Douglas Gregorb9790342010-01-22 21:44:22 +00002874} // end: extern "C"
2875
Douglas Gregor1db19de2010-01-19 21:36:55 +00002876//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002877// CXFile Operations.
2878//===----------------------------------------------------------------------===//
2879
2880extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002881CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002882 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002883 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002884
Steve Naroff88145032009-10-27 14:35:18 +00002885 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002886 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002887}
2888
2889time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002890 if (!SFile)
2891 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002892
Steve Naroff88145032009-10-27 14:35:18 +00002893 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2894 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002895}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002896
Douglas Gregorb9790342010-01-22 21:44:22 +00002897CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2898 if (!tu)
2899 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002900
Ted Kremeneka60ed472010-11-16 08:15:36 +00002901 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002902
Douglas Gregorb9790342010-01-22 21:44:22 +00002903 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002904 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002905}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002906
Douglas Gregordd3e5542011-05-04 00:14:37 +00002907unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) {
2908 if (!tu || !file)
2909 return 0;
2910
2911 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
2912 FileEntry *FEnt = static_cast<FileEntry *>(file);
2913 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2914 .isFileMultipleIncludeGuarded(FEnt);
2915}
2916
Ted Kremenekfb480492010-01-13 21:46:36 +00002917} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002918
Ted Kremenekfb480492010-01-13 21:46:36 +00002919//===----------------------------------------------------------------------===//
2920// CXCursor Operations.
2921//===----------------------------------------------------------------------===//
2922
Ted Kremenekfb480492010-01-13 21:46:36 +00002923static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002924 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2925 return getDeclFromExpr(CE->getSubExpr());
2926
Ted Kremenekfb480492010-01-13 21:46:36 +00002927 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2928 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002929 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2930 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002931 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2932 return ME->getMemberDecl();
2933 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2934 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002935 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002936 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002937
Ted Kremenekfb480492010-01-13 21:46:36 +00002938 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2939 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002940 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2941 if (!CE->isElidable())
2942 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002943 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2944 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002945
Douglas Gregordb1314e2010-10-01 21:11:22 +00002946 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2947 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002948 if (SubstNonTypeTemplateParmPackExpr *NTTP
2949 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2950 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002951 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2952 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2953 isa<ParmVarDecl>(SizeOfPack->getPack()))
2954 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002955
Ted Kremenekfb480492010-01-13 21:46:36 +00002956 return 0;
2957}
2958
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002959static SourceLocation getLocationFromExpr(Expr *E) {
2960 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2961 return /*FIXME:*/Msg->getLeftLoc();
2962 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2963 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002964 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2965 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002966 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2967 return Member->getMemberLoc();
2968 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2969 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002970 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2971 return SizeOfPack->getPackLoc();
2972
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002973 return E->getLocStart();
2974}
2975
Ted Kremenekfb480492010-01-13 21:46:36 +00002976extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002977
2978unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002979 CXCursorVisitor visitor,
2980 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002981 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00002982 getCursorASTUnit(parent)->getMaxPCHLevel(),
2983 false);
Douglas Gregorb1373d02010-01-20 20:59:29 +00002984 return CursorVis.VisitChildren(parent);
2985}
2986
David Chisnall3387c652010-11-03 14:12:26 +00002987#ifndef __has_feature
2988#define __has_feature(x) 0
2989#endif
2990#if __has_feature(blocks)
2991typedef enum CXChildVisitResult
2992 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2993
2994static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2995 CXClientData client_data) {
2996 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2997 return block(cursor, parent);
2998}
2999#else
3000// If we are compiled with a compiler that doesn't have native blocks support,
3001// define and call the block manually, so the
3002typedef struct _CXChildVisitResult
3003{
3004 void *isa;
3005 int flags;
3006 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00003007 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3008 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00003009} *CXCursorVisitorBlock;
3010
3011static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3012 CXClientData client_data) {
3013 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3014 return block->invoke(block, cursor, parent);
3015}
3016#endif
3017
3018
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00003019unsigned clang_visitChildrenWithBlock(CXCursor parent,
3020 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00003021 return clang_visitChildren(parent, visitWithBlock, block);
3022}
3023
Douglas Gregor78205d42010-01-20 21:45:58 +00003024static CXString getDeclSpelling(Decl *D) {
3025 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003026 if (!ND) {
3027 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3028 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3029 return createCXString(Property->getIdentifier()->getName());
3030
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003031 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00003032 }
3033
Douglas Gregor78205d42010-01-20 21:45:58 +00003034 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003035 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003036
Douglas Gregor78205d42010-01-20 21:45:58 +00003037 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
3038 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3039 // and returns different names. NamedDecl returns the class name and
3040 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003041 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003042
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003043 if (isa<UsingDirectiveDecl>(D))
3044 return createCXString("");
3045
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00003046 llvm::SmallString<1024> S;
3047 llvm::raw_svector_ostream os(S);
3048 ND->printName(os);
3049
3050 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00003051}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003052
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003053CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003054 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003055 return clang_getTranslationUnitSpelling(
3056 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003057
Steve Narofff334b4e2009-09-02 18:26:48 +00003058 if (clang_isReference(C.kind)) {
3059 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00003060 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00003061 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003062 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003063 }
3064 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00003065 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003066 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003067 }
3068 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00003069 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00003070 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003071 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003072 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00003073 case CXCursor_CXXBaseSpecifier: {
3074 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3075 return createCXString(B->getType().getAsString());
3076 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003077 case CXCursor_TypeRef: {
3078 TypeDecl *Type = getCursorTypeRef(C).first;
3079 assert(Type && "Missing type decl");
3080
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003081 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3082 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003083 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003084 case CXCursor_TemplateRef: {
3085 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00003086 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003087
3088 return createCXString(Template->getNameAsString());
3089 }
Douglas Gregor69319002010-08-31 23:48:11 +00003090
3091 case CXCursor_NamespaceRef: {
3092 NamedDecl *NS = getCursorNamespaceRef(C).first;
3093 assert(NS && "Missing namespace decl");
3094
3095 return createCXString(NS->getNameAsString());
3096 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003097
Douglas Gregora67e03f2010-09-09 21:42:20 +00003098 case CXCursor_MemberRef: {
3099 FieldDecl *Field = getCursorMemberRef(C).first;
3100 assert(Field && "Missing member decl");
3101
3102 return createCXString(Field->getNameAsString());
3103 }
3104
Douglas Gregor36897b02010-09-10 00:22:18 +00003105 case CXCursor_LabelRef: {
3106 LabelStmt *Label = getCursorLabelRef(C).first;
3107 assert(Label && "Missing label");
3108
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003109 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003110 }
3111
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003112 case CXCursor_OverloadedDeclRef: {
3113 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3114 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3115 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3116 return createCXString(ND->getNameAsString());
3117 return createCXString("");
3118 }
3119 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3120 return createCXString(E->getName().getAsString());
3121 OverloadedTemplateStorage *Ovl
3122 = Storage.get<OverloadedTemplateStorage*>();
3123 if (Ovl->size() == 0)
3124 return createCXString("");
3125 return createCXString((*Ovl->begin())->getNameAsString());
3126 }
3127
Daniel Dunbaracca7252009-11-30 20:42:49 +00003128 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003129 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003130 }
3131 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003132
3133 if (clang_isExpression(C.kind)) {
3134 Decl *D = getDeclFromExpr(getCursorExpr(C));
3135 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003136 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003137 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003138 }
3139
Douglas Gregor36897b02010-09-10 00:22:18 +00003140 if (clang_isStatement(C.kind)) {
3141 Stmt *S = getCursorStmt(C);
3142 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003143 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003144
3145 return createCXString("");
3146 }
3147
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003148 if (C.kind == CXCursor_MacroInstantiation)
3149 return createCXString(getCursorMacroInstantiation(C)->getName()
3150 ->getNameStart());
3151
Douglas Gregor572feb22010-03-18 18:04:21 +00003152 if (C.kind == CXCursor_MacroDefinition)
3153 return createCXString(getCursorMacroDefinition(C)->getName()
3154 ->getNameStart());
3155
Douglas Gregorecdcb882010-10-20 22:00:55 +00003156 if (C.kind == CXCursor_InclusionDirective)
3157 return createCXString(getCursorInclusionDirective(C)->getFileName());
3158
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003159 if (clang_isDeclaration(C.kind))
3160 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003161
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003162 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003163}
3164
Douglas Gregor358559d2010-10-02 22:49:11 +00003165CXString clang_getCursorDisplayName(CXCursor C) {
3166 if (!clang_isDeclaration(C.kind))
3167 return clang_getCursorSpelling(C);
3168
3169 Decl *D = getCursorDecl(C);
3170 if (!D)
3171 return createCXString("");
3172
3173 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3174 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3175 D = FunTmpl->getTemplatedDecl();
3176
3177 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3178 llvm::SmallString<64> Str;
3179 llvm::raw_svector_ostream OS(Str);
3180 OS << Function->getNameAsString();
3181 if (Function->getPrimaryTemplate())
3182 OS << "<>";
3183 OS << "(";
3184 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3185 if (I)
3186 OS << ", ";
3187 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3188 }
3189
3190 if (Function->isVariadic()) {
3191 if (Function->getNumParams())
3192 OS << ", ";
3193 OS << "...";
3194 }
3195 OS << ")";
3196 return createCXString(OS.str());
3197 }
3198
3199 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3200 llvm::SmallString<64> Str;
3201 llvm::raw_svector_ostream OS(Str);
3202 OS << ClassTemplate->getNameAsString();
3203 OS << "<";
3204 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3205 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3206 if (I)
3207 OS << ", ";
3208
3209 NamedDecl *Param = Params->getParam(I);
3210 if (Param->getIdentifier()) {
3211 OS << Param->getIdentifier()->getName();
3212 continue;
3213 }
3214
3215 // There is no parameter name, which makes this tricky. Try to come up
3216 // with something useful that isn't too long.
3217 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3218 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3219 else if (NonTypeTemplateParmDecl *NTTP
3220 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3221 OS << NTTP->getType().getAsString(Policy);
3222 else
3223 OS << "template<...> class";
3224 }
3225
3226 OS << ">";
3227 return createCXString(OS.str());
3228 }
3229
3230 if (ClassTemplateSpecializationDecl *ClassSpec
3231 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3232 // If the type was explicitly written, use that.
3233 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3234 return createCXString(TSInfo->getType().getAsString(Policy));
3235
3236 llvm::SmallString<64> Str;
3237 llvm::raw_svector_ostream OS(Str);
3238 OS << ClassSpec->getNameAsString();
3239 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003240 ClassSpec->getTemplateArgs().data(),
3241 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003242 Policy);
3243 return createCXString(OS.str());
3244 }
3245
3246 return clang_getCursorSpelling(C);
3247}
3248
Ted Kremeneke68fff62010-02-17 00:41:32 +00003249CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003250 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003251 case CXCursor_FunctionDecl:
3252 return createCXString("FunctionDecl");
3253 case CXCursor_TypedefDecl:
3254 return createCXString("TypedefDecl");
3255 case CXCursor_EnumDecl:
3256 return createCXString("EnumDecl");
3257 case CXCursor_EnumConstantDecl:
3258 return createCXString("EnumConstantDecl");
3259 case CXCursor_StructDecl:
3260 return createCXString("StructDecl");
3261 case CXCursor_UnionDecl:
3262 return createCXString("UnionDecl");
3263 case CXCursor_ClassDecl:
3264 return createCXString("ClassDecl");
3265 case CXCursor_FieldDecl:
3266 return createCXString("FieldDecl");
3267 case CXCursor_VarDecl:
3268 return createCXString("VarDecl");
3269 case CXCursor_ParmDecl:
3270 return createCXString("ParmDecl");
3271 case CXCursor_ObjCInterfaceDecl:
3272 return createCXString("ObjCInterfaceDecl");
3273 case CXCursor_ObjCCategoryDecl:
3274 return createCXString("ObjCCategoryDecl");
3275 case CXCursor_ObjCProtocolDecl:
3276 return createCXString("ObjCProtocolDecl");
3277 case CXCursor_ObjCPropertyDecl:
3278 return createCXString("ObjCPropertyDecl");
3279 case CXCursor_ObjCIvarDecl:
3280 return createCXString("ObjCIvarDecl");
3281 case CXCursor_ObjCInstanceMethodDecl:
3282 return createCXString("ObjCInstanceMethodDecl");
3283 case CXCursor_ObjCClassMethodDecl:
3284 return createCXString("ObjCClassMethodDecl");
3285 case CXCursor_ObjCImplementationDecl:
3286 return createCXString("ObjCImplementationDecl");
3287 case CXCursor_ObjCCategoryImplDecl:
3288 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003289 case CXCursor_CXXMethod:
3290 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003291 case CXCursor_UnexposedDecl:
3292 return createCXString("UnexposedDecl");
3293 case CXCursor_ObjCSuperClassRef:
3294 return createCXString("ObjCSuperClassRef");
3295 case CXCursor_ObjCProtocolRef:
3296 return createCXString("ObjCProtocolRef");
3297 case CXCursor_ObjCClassRef:
3298 return createCXString("ObjCClassRef");
3299 case CXCursor_TypeRef:
3300 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003301 case CXCursor_TemplateRef:
3302 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003303 case CXCursor_NamespaceRef:
3304 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003305 case CXCursor_MemberRef:
3306 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003307 case CXCursor_LabelRef:
3308 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003309 case CXCursor_OverloadedDeclRef:
3310 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003311 case CXCursor_UnexposedExpr:
3312 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003313 case CXCursor_BlockExpr:
3314 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003315 case CXCursor_DeclRefExpr:
3316 return createCXString("DeclRefExpr");
3317 case CXCursor_MemberRefExpr:
3318 return createCXString("MemberRefExpr");
3319 case CXCursor_CallExpr:
3320 return createCXString("CallExpr");
3321 case CXCursor_ObjCMessageExpr:
3322 return createCXString("ObjCMessageExpr");
3323 case CXCursor_UnexposedStmt:
3324 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003325 case CXCursor_LabelStmt:
3326 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003327 case CXCursor_InvalidFile:
3328 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003329 case CXCursor_InvalidCode:
3330 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003331 case CXCursor_NoDeclFound:
3332 return createCXString("NoDeclFound");
3333 case CXCursor_NotImplemented:
3334 return createCXString("NotImplemented");
3335 case CXCursor_TranslationUnit:
3336 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003337 case CXCursor_UnexposedAttr:
3338 return createCXString("UnexposedAttr");
3339 case CXCursor_IBActionAttr:
3340 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003341 case CXCursor_IBOutletAttr:
3342 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003343 case CXCursor_IBOutletCollectionAttr:
3344 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003345 case CXCursor_PreprocessingDirective:
3346 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003347 case CXCursor_MacroDefinition:
3348 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003349 case CXCursor_MacroInstantiation:
3350 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003351 case CXCursor_InclusionDirective:
3352 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003353 case CXCursor_Namespace:
3354 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003355 case CXCursor_LinkageSpec:
3356 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003357 case CXCursor_CXXBaseSpecifier:
3358 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003359 case CXCursor_Constructor:
3360 return createCXString("CXXConstructor");
3361 case CXCursor_Destructor:
3362 return createCXString("CXXDestructor");
3363 case CXCursor_ConversionFunction:
3364 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003365 case CXCursor_TemplateTypeParameter:
3366 return createCXString("TemplateTypeParameter");
3367 case CXCursor_NonTypeTemplateParameter:
3368 return createCXString("NonTypeTemplateParameter");
3369 case CXCursor_TemplateTemplateParameter:
3370 return createCXString("TemplateTemplateParameter");
3371 case CXCursor_FunctionTemplate:
3372 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003373 case CXCursor_ClassTemplate:
3374 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003375 case CXCursor_ClassTemplatePartialSpecialization:
3376 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003377 case CXCursor_NamespaceAlias:
3378 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003379 case CXCursor_UsingDirective:
3380 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003381 case CXCursor_UsingDeclaration:
3382 return createCXString("UsingDeclaration");
Richard Smith162e1c12011-04-15 14:24:37 +00003383 case CXCursor_TypeAliasDecl:
Douglas Gregor352697a2011-06-03 23:08:58 +00003384 return createCXString("TypeAliasDecl");
3385 case CXCursor_ObjCSynthesizeDecl:
3386 return createCXString("ObjCSynthesizeDecl");
3387 case CXCursor_ObjCDynamicDecl:
3388 return createCXString("ObjCDynamicDecl");
Steve Naroff89922f82009-08-31 00:59:03 +00003389 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003390
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003391 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003392 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003393}
Steve Naroff89922f82009-08-31 00:59:03 +00003394
Ted Kremeneke68fff62010-02-17 00:41:32 +00003395enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3396 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003397 CXClientData client_data) {
3398 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003399
3400 // If our current best cursor is the construction of a temporary object,
3401 // don't replace that cursor with a type reference, because we want
3402 // clang_getCursor() to point at the constructor.
3403 if (clang_isExpression(BestCursor->kind) &&
3404 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3405 cursor.kind == CXCursor_TypeRef)
3406 return CXChildVisit_Recurse;
3407
Douglas Gregor85fe1562010-12-10 07:23:11 +00003408 // Don't override a preprocessing cursor with another preprocessing
3409 // cursor; we want the outermost preprocessing cursor.
3410 if (clang_isPreprocessing(cursor.kind) &&
3411 clang_isPreprocessing(BestCursor->kind))
3412 return CXChildVisit_Recurse;
3413
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003414 *BestCursor = cursor;
3415 return CXChildVisit_Recurse;
3416}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003417
Douglas Gregorb9790342010-01-22 21:44:22 +00003418CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3419 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003420 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003421
Ted Kremeneka60ed472010-11-16 08:15:36 +00003422 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003423 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3424
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003425 // Translate the given source location to make it point at the beginning of
3426 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003427 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003428
3429 // Guard against an invalid SourceLocation, or we may assert in one
3430 // of the following calls.
3431 if (SLoc.isInvalid())
3432 return clang_getNullCursor();
3433
Douglas Gregor40749ee2010-11-03 00:35:38 +00003434 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003435 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3436 CXXUnit->getASTContext().getLangOptions());
3437
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003438 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3439 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003440 // FIXME: Would be great to have a "hint" cursor, then walk from that
3441 // hint cursor upward until we find a cursor whose source range encloses
3442 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003443 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3444 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00003445 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003446 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003447 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003448
3449 if (Logging) {
3450 CXFile SearchFile;
3451 unsigned SearchLine, SearchColumn;
3452 CXFile ResultFile;
3453 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003454 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3455 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003456 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3457
3458 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3459 0);
3460 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3461 &ResultColumn, 0);
3462 SearchFileName = clang_getFileName(SearchFile);
3463 ResultFileName = clang_getFileName(ResultFile);
3464 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003465 USR = clang_getCursorUSR(Result);
3466 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003467 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3468 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003469 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3470 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003471 clang_disposeString(SearchFileName);
3472 clang_disposeString(ResultFileName);
3473 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003474 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003475
3476 CXCursor Definition = clang_getCursorDefinition(Result);
3477 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3478 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3479 CXString DefinitionKindSpelling
3480 = clang_getCursorKindSpelling(Definition.kind);
3481 CXFile DefinitionFile;
3482 unsigned DefinitionLine, DefinitionColumn;
3483 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3484 &DefinitionLine, &DefinitionColumn, 0);
3485 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3486 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3487 clang_getCString(DefinitionKindSpelling),
3488 clang_getCString(DefinitionFileName),
3489 DefinitionLine, DefinitionColumn);
3490 clang_disposeString(DefinitionFileName);
3491 clang_disposeString(DefinitionKindSpelling);
3492 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003493 }
3494
Ted Kremeneke68fff62010-02-17 00:41:32 +00003495 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003496}
3497
Ted Kremenek73885552009-11-17 19:28:59 +00003498CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003499 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003500}
3501
3502unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003503 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003504}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003505
Douglas Gregor9ce55842010-11-20 00:09:34 +00003506unsigned clang_hashCursor(CXCursor C) {
3507 unsigned Index = 0;
3508 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3509 Index = 1;
3510
3511 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3512 std::make_pair(C.kind, C.data[Index]));
3513}
3514
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003515unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003516 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3517}
3518
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003519unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003520 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3521}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003522
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003523unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003524 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3525}
3526
Douglas Gregor97b98722010-01-19 23:20:36 +00003527unsigned clang_isExpression(enum CXCursorKind K) {
3528 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3529}
3530
3531unsigned clang_isStatement(enum CXCursorKind K) {
3532 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3533}
3534
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003535unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3536 return K == CXCursor_TranslationUnit;
3537}
3538
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003539unsigned clang_isPreprocessing(enum CXCursorKind K) {
3540 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3541}
3542
Ted Kremenekad6eff62010-03-08 21:17:29 +00003543unsigned clang_isUnexposed(enum CXCursorKind K) {
3544 switch (K) {
3545 case CXCursor_UnexposedDecl:
3546 case CXCursor_UnexposedExpr:
3547 case CXCursor_UnexposedStmt:
3548 case CXCursor_UnexposedAttr:
3549 return true;
3550 default:
3551 return false;
3552 }
3553}
3554
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003555CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003556 return C.kind;
3557}
3558
Douglas Gregor98258af2010-01-18 22:46:11 +00003559CXSourceLocation clang_getCursorLocation(CXCursor C) {
3560 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003561 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003562 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003563 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3564 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003565 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003566 }
3567
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003568 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003569 std::pair<ObjCProtocolDecl *, SourceLocation> P
3570 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003571 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003572 }
3573
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003574 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003575 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3576 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003577 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003578 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003579
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003580 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003581 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003582 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003583 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003584
3585 case CXCursor_TemplateRef: {
3586 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3587 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3588 }
3589
Douglas Gregor69319002010-08-31 23:48:11 +00003590 case CXCursor_NamespaceRef: {
3591 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3592 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3593 }
3594
Douglas Gregora67e03f2010-09-09 21:42:20 +00003595 case CXCursor_MemberRef: {
3596 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3597 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3598 }
3599
Ted Kremenek3064ef92010-08-27 21:34:58 +00003600 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003601 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3602 if (!BaseSpec)
3603 return clang_getNullLocation();
3604
3605 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3606 return cxloc::translateSourceLocation(getCursorContext(C),
3607 TSInfo->getTypeLoc().getBeginLoc());
3608
3609 return cxloc::translateSourceLocation(getCursorContext(C),
3610 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003611 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003612
Douglas Gregor36897b02010-09-10 00:22:18 +00003613 case CXCursor_LabelRef: {
3614 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3615 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3616 }
3617
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003618 case CXCursor_OverloadedDeclRef:
3619 return cxloc::translateSourceLocation(getCursorContext(C),
3620 getCursorOverloadedDeclRef(C).second);
3621
Douglas Gregorf46034a2010-01-18 23:41:10 +00003622 default:
3623 // FIXME: Need a way to enumerate all non-reference cases.
3624 llvm_unreachable("Missed a reference kind");
3625 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003626 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003627
3628 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003629 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003630 getLocationFromExpr(getCursorExpr(C)));
3631
Douglas Gregor36897b02010-09-10 00:22:18 +00003632 if (clang_isStatement(C.kind))
3633 return cxloc::translateSourceLocation(getCursorContext(C),
3634 getCursorStmt(C)->getLocStart());
3635
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003636 if (C.kind == CXCursor_PreprocessingDirective) {
3637 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3638 return cxloc::translateSourceLocation(getCursorContext(C), L);
3639 }
Douglas Gregor48072312010-03-18 15:23:44 +00003640
3641 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003642 SourceLocation L
3643 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003644 return cxloc::translateSourceLocation(getCursorContext(C), L);
3645 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003646
3647 if (C.kind == CXCursor_MacroDefinition) {
3648 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3649 return cxloc::translateSourceLocation(getCursorContext(C), L);
3650 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003651
3652 if (C.kind == CXCursor_InclusionDirective) {
3653 SourceLocation L
3654 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3655 return cxloc::translateSourceLocation(getCursorContext(C), L);
3656 }
3657
Ted Kremenek9a700d22010-05-12 06:16:13 +00003658 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003659 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003660
Douglas Gregorf46034a2010-01-18 23:41:10 +00003661 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003662 SourceLocation Loc = D->getLocation();
3663 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3664 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003665 // FIXME: Multiple variables declared in a single declaration
3666 // currently lack the information needed to correctly determine their
3667 // ranges when accounting for the type-specifier. We use context
3668 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3669 // and if so, whether it is the first decl.
3670 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3671 if (!cxcursor::isFirstInDeclGroup(C))
3672 Loc = VD->getLocation();
3673 }
3674
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003675 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003676}
Douglas Gregora7bde202010-01-19 00:34:46 +00003677
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003678} // end extern "C"
3679
3680static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003681 if (clang_isReference(C.kind)) {
3682 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003683 case CXCursor_ObjCSuperClassRef:
3684 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003685
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003686 case CXCursor_ObjCProtocolRef:
3687 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003688
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003689 case CXCursor_ObjCClassRef:
3690 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003691
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003692 case CXCursor_TypeRef:
3693 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003694
3695 case CXCursor_TemplateRef:
3696 return getCursorTemplateRef(C).second;
3697
Douglas Gregor69319002010-08-31 23:48:11 +00003698 case CXCursor_NamespaceRef:
3699 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003700
3701 case CXCursor_MemberRef:
3702 return getCursorMemberRef(C).second;
3703
Ted Kremenek3064ef92010-08-27 21:34:58 +00003704 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003705 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003706
Douglas Gregor36897b02010-09-10 00:22:18 +00003707 case CXCursor_LabelRef:
3708 return getCursorLabelRef(C).second;
3709
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003710 case CXCursor_OverloadedDeclRef:
3711 return getCursorOverloadedDeclRef(C).second;
3712
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003713 default:
3714 // FIXME: Need a way to enumerate all non-reference cases.
3715 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003716 }
3717 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003718
3719 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003720 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003721
3722 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003723 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003724
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003725 if (C.kind == CXCursor_PreprocessingDirective)
3726 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003727
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003728 if (C.kind == CXCursor_MacroInstantiation)
3729 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003730
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003731 if (C.kind == CXCursor_MacroDefinition)
3732 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003733
3734 if (C.kind == CXCursor_InclusionDirective)
3735 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3736
Ted Kremenek007a7c92010-11-01 23:26:51 +00003737 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3738 Decl *D = cxcursor::getCursorDecl(C);
3739 SourceRange R = D->getSourceRange();
3740 // FIXME: Multiple variables declared in a single declaration
3741 // currently lack the information needed to correctly determine their
3742 // ranges when accounting for the type-specifier. We use context
3743 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3744 // and if so, whether it is the first decl.
3745 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3746 if (!cxcursor::isFirstInDeclGroup(C))
3747 R.setBegin(VD->getLocation());
3748 }
3749 return R;
3750 }
Douglas Gregor66537982010-11-17 17:14:07 +00003751 return SourceRange();
3752}
3753
3754/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3755/// the decl-specifier-seq for declarations.
3756static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3757 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3758 Decl *D = cxcursor::getCursorDecl(C);
3759 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003760
Douglas Gregor2494dd02011-03-01 01:34:45 +00003761 // Adjust the start of the location for declarations preceded by
3762 // declaration specifiers.
3763 SourceLocation StartLoc;
3764 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3765 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3766 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3767 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3768 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3769 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3770 }
3771
3772 if (StartLoc.isValid() && R.getBegin().isValid() &&
3773 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3774 R.setBegin(StartLoc);
3775
3776 // FIXME: Multiple variables declared in a single declaration
3777 // currently lack the information needed to correctly determine their
3778 // ranges when accounting for the type-specifier. We use context
3779 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3780 // and if so, whether it is the first decl.
3781 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3782 if (!cxcursor::isFirstInDeclGroup(C))
3783 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003784 }
3785
3786 return R;
3787 }
3788
3789 return getRawCursorExtent(C);
3790}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003791
3792extern "C" {
3793
3794CXSourceRange clang_getCursorExtent(CXCursor C) {
3795 SourceRange R = getRawCursorExtent(C);
3796 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003797 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003798
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003799 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003800}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003801
3802CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003803 if (clang_isInvalid(C.kind))
3804 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003805
Ted Kremeneka60ed472010-11-16 08:15:36 +00003806 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003807 if (clang_isDeclaration(C.kind)) {
3808 Decl *D = getCursorDecl(C);
3809 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003810 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003811 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003812 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003813 if (ObjCForwardProtocolDecl *Protocols
3814 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003815 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003816 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3817 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3818 return MakeCXCursor(Property, tu);
3819
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003820 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003821 }
3822
Douglas Gregor97b98722010-01-19 23:20:36 +00003823 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003824 Expr *E = getCursorExpr(C);
3825 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003826 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003827 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003828
3829 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003830 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003831
Douglas Gregor97b98722010-01-19 23:20:36 +00003832 return clang_getNullCursor();
3833 }
3834
Douglas Gregor36897b02010-09-10 00:22:18 +00003835 if (clang_isStatement(C.kind)) {
3836 Stmt *S = getCursorStmt(C);
3837 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek37c2e962011-03-15 23:47:49 +00003838 if (LabelDecl *label = Goto->getLabel())
3839 if (LabelStmt *labelS = label->getStmt())
3840 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003841
3842 return clang_getNullCursor();
3843 }
3844
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003845 if (C.kind == CXCursor_MacroInstantiation) {
3846 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003847 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003848 }
3849
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003850 if (!clang_isReference(C.kind))
3851 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003852
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003853 switch (C.kind) {
3854 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003855 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003856
3857 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003858 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003859
3860 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003861 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003862
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003863 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003864 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003865
3866 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003867 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003868
Douglas Gregor69319002010-08-31 23:48:11 +00003869 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003870 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003871
Douglas Gregora67e03f2010-09-09 21:42:20 +00003872 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003873 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003874
Ted Kremenek3064ef92010-08-27 21:34:58 +00003875 case CXCursor_CXXBaseSpecifier: {
3876 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3877 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003878 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003879 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003880
Douglas Gregor36897b02010-09-10 00:22:18 +00003881 case CXCursor_LabelRef:
3882 // FIXME: We end up faking the "parent" declaration here because we
3883 // don't want to make CXCursor larger.
3884 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003885 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3886 .getTranslationUnitDecl(),
3887 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003888
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003889 case CXCursor_OverloadedDeclRef:
3890 return C;
3891
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003892 default:
3893 // We would prefer to enumerate all non-reference cursor kinds here.
3894 llvm_unreachable("Unhandled reference cursor kind");
3895 break;
3896 }
3897 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003898
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003899 return clang_getNullCursor();
3900}
3901
Douglas Gregorb6998662010-01-19 19:34:47 +00003902CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003903 if (clang_isInvalid(C.kind))
3904 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003905
Ted Kremeneka60ed472010-11-16 08:15:36 +00003906 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003907
Douglas Gregorb6998662010-01-19 19:34:47 +00003908 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003909 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003910 C = clang_getCursorReferenced(C);
3911 WasReference = true;
3912 }
3913
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003914 if (C.kind == CXCursor_MacroInstantiation)
3915 return clang_getCursorReferenced(C);
3916
Douglas Gregorb6998662010-01-19 19:34:47 +00003917 if (!clang_isDeclaration(C.kind))
3918 return clang_getNullCursor();
3919
3920 Decl *D = getCursorDecl(C);
3921 if (!D)
3922 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003923
Douglas Gregorb6998662010-01-19 19:34:47 +00003924 switch (D->getKind()) {
3925 // Declaration kinds that don't really separate the notions of
3926 // declaration and definition.
3927 case Decl::Namespace:
3928 case Decl::Typedef:
Richard Smith162e1c12011-04-15 14:24:37 +00003929 case Decl::TypeAlias:
Richard Smith3e4c6c42011-05-05 21:57:07 +00003930 case Decl::TypeAliasTemplate:
Douglas Gregorb6998662010-01-19 19:34:47 +00003931 case Decl::TemplateTypeParm:
3932 case Decl::EnumConstant:
3933 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003934 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003935 case Decl::ObjCIvar:
3936 case Decl::ObjCAtDefsField:
3937 case Decl::ImplicitParam:
3938 case Decl::ParmVar:
3939 case Decl::NonTypeTemplateParm:
3940 case Decl::TemplateTemplateParm:
3941 case Decl::ObjCCategoryImpl:
3942 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003943 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003944 case Decl::LinkageSpec:
3945 case Decl::ObjCPropertyImpl:
3946 case Decl::FileScopeAsm:
3947 case Decl::StaticAssert:
3948 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003949 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003950 return C;
3951
3952 // Declaration kinds that don't make any sense here, but are
3953 // nonetheless harmless.
3954 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003955 break;
3956
3957 // Declaration kinds for which the definition is not resolvable.
3958 case Decl::UnresolvedUsingTypename:
3959 case Decl::UnresolvedUsingValue:
3960 break;
3961
3962 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003963 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003964 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003965
3966 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003967 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003968
3969 case Decl::Enum:
3970 case Decl::Record:
3971 case Decl::CXXRecord:
3972 case Decl::ClassTemplateSpecialization:
3973 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003974 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003975 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003976 return clang_getNullCursor();
3977
3978 case Decl::Function:
3979 case Decl::CXXMethod:
3980 case Decl::CXXConstructor:
3981 case Decl::CXXDestructor:
3982 case Decl::CXXConversion: {
3983 const FunctionDecl *Def = 0;
3984 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003985 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003986 return clang_getNullCursor();
3987 }
3988
3989 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003990 // Ask the variable if it has a definition.
3991 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003992 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003993 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003994 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003995
Douglas Gregorb6998662010-01-19 19:34:47 +00003996 case Decl::FunctionTemplate: {
3997 const FunctionDecl *Def = 0;
3998 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003999 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004000 return clang_getNullCursor();
4001 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004002
Douglas Gregorb6998662010-01-19 19:34:47 +00004003 case Decl::ClassTemplate: {
4004 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00004005 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00004006 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004007 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004008 return clang_getNullCursor();
4009 }
4010
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004011 case Decl::Using:
4012 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004013 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004014
4015 case Decl::UsingShadow:
4016 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004017 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004018 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004019
4020 case Decl::ObjCMethod: {
4021 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
4022 if (Method->isThisDeclarationADefinition())
4023 return C;
4024
4025 // Dig out the method definition in the associated
4026 // @implementation, if we have it.
4027 // FIXME: The ASTs should make finding the definition easier.
4028 if (ObjCInterfaceDecl *Class
4029 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4030 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4031 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4032 Method->isInstanceMethod()))
4033 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004034 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004035
4036 return clang_getNullCursor();
4037 }
4038
4039 case Decl::ObjCCategory:
4040 if (ObjCCategoryImplDecl *Impl
4041 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004042 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004043 return clang_getNullCursor();
4044
4045 case Decl::ObjCProtocol:
4046 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
4047 return C;
4048 return clang_getNullCursor();
4049
4050 case Decl::ObjCInterface:
4051 // There are two notions of a "definition" for an Objective-C
4052 // class: the interface and its implementation. When we resolved a
4053 // reference to an Objective-C class, produce the @interface as
4054 // the definition; when we were provided with the interface,
4055 // produce the @implementation as the definition.
4056 if (WasReference) {
4057 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4058 return C;
4059 } else if (ObjCImplementationDecl *Impl
4060 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004061 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004062 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004063
Douglas Gregorb6998662010-01-19 19:34:47 +00004064 case Decl::ObjCProperty:
4065 // FIXME: We don't really know where to find the
4066 // ObjCPropertyImplDecls that implement this property.
4067 return clang_getNullCursor();
4068
4069 case Decl::ObjCCompatibleAlias:
4070 if (ObjCInterfaceDecl *Class
4071 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4072 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004073 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004074
Douglas Gregorb6998662010-01-19 19:34:47 +00004075 return clang_getNullCursor();
4076
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004077 case Decl::ObjCForwardProtocol:
4078 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004079 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004080
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004081 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004082 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004083 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004084
4085 case Decl::Friend:
4086 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004087 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004088 return clang_getNullCursor();
4089
4090 case Decl::FriendTemplate:
4091 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004092 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004093 return clang_getNullCursor();
4094 }
4095
4096 return clang_getNullCursor();
4097}
4098
4099unsigned clang_isCursorDefinition(CXCursor C) {
4100 if (!clang_isDeclaration(C.kind))
4101 return 0;
4102
4103 return clang_getCursorDefinition(C) == C;
4104}
4105
Douglas Gregor1a9d0502010-11-19 23:44:15 +00004106CXCursor clang_getCanonicalCursor(CXCursor C) {
4107 if (!clang_isDeclaration(C.kind))
4108 return C;
4109
4110 if (Decl *D = getCursorDecl(C))
4111 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4112
4113 return C;
4114}
4115
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004116unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004117 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004118 return 0;
4119
4120 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4121 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4122 return E->getNumDecls();
4123
4124 if (OverloadedTemplateStorage *S
4125 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4126 return S->size();
4127
4128 Decl *D = Storage.get<Decl*>();
4129 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00004130 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004131 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4132 return Classes->size();
4133 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4134 return Protocols->protocol_size();
4135
4136 return 0;
4137}
4138
4139CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004140 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004141 return clang_getNullCursor();
4142
4143 if (index >= clang_getNumOverloadedDecls(cursor))
4144 return clang_getNullCursor();
4145
Ted Kremeneka60ed472010-11-16 08:15:36 +00004146 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004147 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4148 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004149 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004150
4151 if (OverloadedTemplateStorage *S
4152 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004153 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004154
4155 Decl *D = Storage.get<Decl*>();
4156 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4157 // FIXME: This is, unfortunately, linear time.
4158 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4159 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004160 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004161 }
4162
4163 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004164 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004165
4166 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004167 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004168
4169 return clang_getNullCursor();
4170}
4171
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004172void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004173 const char **startBuf,
4174 const char **endBuf,
4175 unsigned *startLine,
4176 unsigned *startColumn,
4177 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004178 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004179 assert(getCursorDecl(C) && "CXCursor has null decl");
4180 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004181 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4182 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004183
Steve Naroff4ade6d62009-09-23 17:52:52 +00004184 SourceManager &SM = FD->getASTContext().getSourceManager();
4185 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4186 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4187 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4188 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4189 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4190 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4191}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004192
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004193void clang_enableStackTraces(void) {
4194 llvm::sys::PrintStackTraceOnErrorSignal();
4195}
4196
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004197void clang_executeOnThread(void (*fn)(void*), void *user_data,
4198 unsigned stack_size) {
4199 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4200}
4201
Ted Kremenekfb480492010-01-13 21:46:36 +00004202} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004203
Ted Kremenekfb480492010-01-13 21:46:36 +00004204//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004205// Token-based Operations.
4206//===----------------------------------------------------------------------===//
4207
4208/* CXToken layout:
4209 * int_data[0]: a CXTokenKind
4210 * int_data[1]: starting token location
4211 * int_data[2]: token length
4212 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004213 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004214 * otherwise unused.
4215 */
4216extern "C" {
4217
4218CXTokenKind clang_getTokenKind(CXToken CXTok) {
4219 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4220}
4221
4222CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4223 switch (clang_getTokenKind(CXTok)) {
4224 case CXToken_Identifier:
4225 case CXToken_Keyword:
4226 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004227 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4228 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004229
4230 case CXToken_Literal: {
4231 // We have stashed the starting pointer in the ptr_data field. Use it.
4232 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004233 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004234 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004235
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004236 case CXToken_Punctuation:
4237 case CXToken_Comment:
4238 break;
4239 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004240
4241 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004242 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004243 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004244 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004245 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004246
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004247 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4248 std::pair<FileID, unsigned> LocInfo
4249 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004250 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004251 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004252 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4253 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004254 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004255
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004256 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004257}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004258
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004259CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004260 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004261 if (!CXXUnit)
4262 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004263
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004264 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4265 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4266}
4267
4268CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004269 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004270 if (!CXXUnit)
4271 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004272
4273 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004274 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4275}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004276
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004277void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4278 CXToken **Tokens, unsigned *NumTokens) {
4279 if (Tokens)
4280 *Tokens = 0;
4281 if (NumTokens)
4282 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004283
Ted Kremeneka60ed472010-11-16 08:15:36 +00004284 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004285 if (!CXXUnit || !Tokens || !NumTokens)
4286 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004287
Douglas Gregorbdf60622010-03-05 21:16:25 +00004288 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4289
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004290 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004291 if (R.isInvalid())
4292 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004293
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004294 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4295 std::pair<FileID, unsigned> BeginLocInfo
4296 = SourceMgr.getDecomposedLoc(R.getBegin());
4297 std::pair<FileID, unsigned> EndLocInfo
4298 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004299
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004300 // Cannot tokenize across files.
4301 if (BeginLocInfo.first != EndLocInfo.first)
4302 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004303
4304 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004305 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004306 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004307 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004308 if (Invalid)
4309 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004310
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004311 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4312 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004313 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004314 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004315
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004316 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004317 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004318 llvm::SmallVector<CXToken, 32> CXTokens;
4319 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004320 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004321 do {
4322 // Lex the next token
4323 Lex.LexFromRawLexer(Tok);
4324 if (Tok.is(tok::eof))
4325 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004326
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004327 // Initialize the CXToken.
4328 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004329
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004330 // - Common fields
4331 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4332 CXTok.int_data[2] = Tok.getLength();
4333 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004334
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004335 // - Kind-specific fields
4336 if (Tok.isLiteral()) {
4337 CXTok.int_data[0] = CXToken_Literal;
4338 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004339 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004340 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004341 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004342 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004343
David Chisnall096428b2010-10-13 21:44:48 +00004344 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004345 CXTok.int_data[0] = CXToken_Keyword;
4346 }
4347 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004348 CXTok.int_data[0] = Tok.is(tok::identifier)
4349 ? CXToken_Identifier
4350 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004351 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004352 CXTok.ptr_data = II;
4353 } else if (Tok.is(tok::comment)) {
4354 CXTok.int_data[0] = CXToken_Comment;
4355 CXTok.ptr_data = 0;
4356 } else {
4357 CXTok.int_data[0] = CXToken_Punctuation;
4358 CXTok.ptr_data = 0;
4359 }
4360 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004361 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004362 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004363
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004364 if (CXTokens.empty())
4365 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004366
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004367 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4368 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4369 *NumTokens = CXTokens.size();
4370}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004371
Ted Kremenek6db61092010-05-05 00:55:15 +00004372void clang_disposeTokens(CXTranslationUnit TU,
4373 CXToken *Tokens, unsigned NumTokens) {
4374 free(Tokens);
4375}
4376
4377} // end: extern "C"
4378
4379//===----------------------------------------------------------------------===//
4380// Token annotation APIs.
4381//===----------------------------------------------------------------------===//
4382
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004383typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004384static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4385 CXCursor parent,
4386 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004387namespace {
4388class AnnotateTokensWorker {
4389 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004390 CXToken *Tokens;
4391 CXCursor *Cursors;
4392 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004393 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004394 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004395 CursorVisitor AnnotateVis;
4396 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004397 bool HasContextSensitiveKeywords;
4398
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004399 bool MoreTokens() const { return TokIdx < NumTokens; }
4400 unsigned NextToken() const { return TokIdx; }
4401 void AdvanceToken() { ++TokIdx; }
4402 SourceLocation GetTokenLoc(unsigned tokI) {
4403 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4404 }
4405
Ted Kremenek6db61092010-05-05 00:55:15 +00004406public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004407 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004408 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004409 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004410 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004411 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004412 AnnotateVis(tu,
4413 AnnotateTokensVisitor, this,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00004414 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004415 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4416 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004417
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004418 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004419 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004420 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004421 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004422 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004423 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004424
4425 /// \brief Determine whether the annotator saw any cursors that have
4426 /// context-sensitive keywords.
4427 bool hasContextSensitiveKeywords() const {
4428 return HasContextSensitiveKeywords;
4429 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004430};
4431}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004432
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004433void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4434 // Walk the AST within the region of interest, annotating tokens
4435 // along the way.
4436 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004437
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004438 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4439 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004440 if (Pos != Annotated.end() &&
4441 (clang_isInvalid(Cursors[I].kind) ||
4442 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004443 Cursors[I] = Pos->second;
4444 }
4445
4446 // Finish up annotating any tokens left.
4447 if (!MoreTokens())
4448 return;
4449
4450 const CXCursor &C = clang_getNullCursor();
4451 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4452 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4453 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004454 }
4455}
4456
Ted Kremenek6db61092010-05-05 00:55:15 +00004457enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004458AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004459 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004460 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004461 if (cursorRange.isInvalid())
4462 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004463
4464 if (!HasContextSensitiveKeywords) {
4465 // Objective-C properties can have context-sensitive keywords.
4466 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4467 if (ObjCPropertyDecl *Property
4468 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4469 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4470 }
4471 // Objective-C methods can have context-sensitive keywords.
4472 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4473 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4474 if (ObjCMethodDecl *Method
4475 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4476 if (Method->getObjCDeclQualifier())
4477 HasContextSensitiveKeywords = true;
4478 else {
4479 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4480 PEnd = Method->param_end();
4481 P != PEnd; ++P) {
4482 if ((*P)->getObjCDeclQualifier()) {
4483 HasContextSensitiveKeywords = true;
4484 break;
4485 }
4486 }
4487 }
4488 }
4489 }
4490 // C++ methods can have context-sensitive keywords.
4491 else if (cursor.kind == CXCursor_CXXMethod) {
4492 if (CXXMethodDecl *Method
4493 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4494 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4495 HasContextSensitiveKeywords = true;
4496 }
4497 }
4498 // C++ classes can have context-sensitive keywords.
4499 else if (cursor.kind == CXCursor_StructDecl ||
4500 cursor.kind == CXCursor_ClassDecl ||
4501 cursor.kind == CXCursor_ClassTemplate ||
4502 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4503 if (Decl *D = getCursorDecl(cursor))
4504 if (D->hasAttr<FinalAttr>())
4505 HasContextSensitiveKeywords = true;
4506 }
4507 }
4508
Douglas Gregor4419b672010-10-21 06:10:04 +00004509 if (clang_isPreprocessing(cursor.kind)) {
4510 // For macro instantiations, just note where the beginning of the macro
4511 // instantiation occurs.
4512 if (cursor.kind == CXCursor_MacroInstantiation) {
4513 Annotated[Loc.int_data] = cursor;
4514 return CXChildVisit_Recurse;
4515 }
4516
Douglas Gregor4419b672010-10-21 06:10:04 +00004517 // Items in the preprocessing record are kept separate from items in
4518 // declarations, so we keep a separate token index.
4519 unsigned SavedTokIdx = TokIdx;
4520 TokIdx = PreprocessingTokIdx;
4521
4522 // Skip tokens up until we catch up to the beginning of the preprocessing
4523 // entry.
4524 while (MoreTokens()) {
4525 const unsigned I = NextToken();
4526 SourceLocation TokLoc = GetTokenLoc(I);
4527 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4528 case RangeBefore:
4529 AdvanceToken();
4530 continue;
4531 case RangeAfter:
4532 case RangeOverlap:
4533 break;
4534 }
4535 break;
4536 }
4537
4538 // Look at all of the tokens within this range.
4539 while (MoreTokens()) {
4540 const unsigned I = NextToken();
4541 SourceLocation TokLoc = GetTokenLoc(I);
4542 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4543 case RangeBefore:
4544 assert(0 && "Infeasible");
4545 case RangeAfter:
4546 break;
4547 case RangeOverlap:
4548 Cursors[I] = cursor;
4549 AdvanceToken();
4550 continue;
4551 }
4552 break;
4553 }
4554
4555 // Save the preprocessing token index; restore the non-preprocessing
4556 // token index.
4557 PreprocessingTokIdx = TokIdx;
4558 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004559 return CXChildVisit_Recurse;
4560 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004561
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004562 if (cursorRange.isInvalid())
4563 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004564
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004565 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4566
Ted Kremeneka333c662010-05-12 05:29:33 +00004567 // Adjust the annotated range based specific declarations.
4568 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4569 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004570 Decl *D = cxcursor::getCursorDecl(cursor);
4571 // Don't visit synthesized ObjC methods, since they have no syntatic
4572 // representation in the source.
4573 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4574 if (MD->isSynthesized())
4575 return CXChildVisit_Continue;
4576 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004577
4578 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004579 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004580 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4581 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4582 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4583 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4584 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004585 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004586
4587 if (StartLoc.isValid() && L.isValid() &&
4588 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4589 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004590 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004591
Ted Kremenek3f404602010-08-14 01:14:06 +00004592 // If the location of the cursor occurs within a macro instantiation, record
4593 // the spelling location of the cursor in our annotation map. We can then
4594 // paper over the token labelings during a post-processing step to try and
4595 // get cursor mappings for tokens that are the *arguments* of a macro
4596 // instantiation.
4597 if (L.isMacroID()) {
4598 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4599 // Only invalidate the old annotation if it isn't part of a preprocessing
4600 // directive. Here we assume that the default construction of CXCursor
4601 // results in CXCursor.kind being an initialized value (i.e., 0). If
4602 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004603
Ted Kremenek3f404602010-08-14 01:14:06 +00004604 CXCursor &oldC = Annotated[rawEncoding];
4605 if (!clang_isPreprocessing(oldC.kind))
4606 oldC = cursor;
4607 }
4608
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004609 const enum CXCursorKind K = clang_getCursorKind(parent);
4610 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004611 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4612 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004613
4614 while (MoreTokens()) {
4615 const unsigned I = NextToken();
4616 SourceLocation TokLoc = GetTokenLoc(I);
4617 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4618 case RangeBefore:
4619 Cursors[I] = updateC;
4620 AdvanceToken();
4621 continue;
4622 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004623 case RangeOverlap:
4624 break;
4625 }
4626 break;
4627 }
4628
4629 // Visit children to get their cursor information.
4630 const unsigned BeforeChildren = NextToken();
4631 VisitChildren(cursor);
4632 const unsigned AfterChildren = NextToken();
4633
4634 // Adjust 'Last' to the last token within the extent of the cursor.
4635 while (MoreTokens()) {
4636 const unsigned I = NextToken();
4637 SourceLocation TokLoc = GetTokenLoc(I);
4638 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4639 case RangeBefore:
4640 assert(0 && "Infeasible");
4641 case RangeAfter:
4642 break;
4643 case RangeOverlap:
4644 Cursors[I] = updateC;
4645 AdvanceToken();
4646 continue;
4647 }
4648 break;
4649 }
4650 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004651
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004652 // Scan the tokens that are at the beginning of the cursor, but are not
4653 // capture by the child cursors.
4654
4655 // For AST elements within macros, rely on a post-annotate pass to
4656 // to correctly annotate the tokens with cursors. Otherwise we can
4657 // get confusing results of having tokens that map to cursors that really
4658 // are expanded by an instantiation.
4659 if (L.isMacroID())
4660 cursor = clang_getNullCursor();
4661
4662 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4663 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4664 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004665
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004666 Cursors[I] = cursor;
4667 }
4668 // Scan the tokens that are at the end of the cursor, but are not captured
4669 // but the child cursors.
4670 for (unsigned I = AfterChildren; I != Last; ++I)
4671 Cursors[I] = cursor;
4672
4673 TokIdx = Last;
4674 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004675}
4676
Ted Kremenek6db61092010-05-05 00:55:15 +00004677static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4678 CXCursor parent,
4679 CXClientData client_data) {
4680 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4681}
4682
Ted Kremenek6628a612011-03-18 22:51:30 +00004683namespace {
4684 struct clang_annotateTokens_Data {
4685 CXTranslationUnit TU;
4686 ASTUnit *CXXUnit;
4687 CXToken *Tokens;
4688 unsigned NumTokens;
4689 CXCursor *Cursors;
4690 };
4691}
4692
Ted Kremenekab979612010-11-11 08:05:23 +00004693// This gets run a separate thread to avoid stack blowout.
Ted Kremenek6628a612011-03-18 22:51:30 +00004694static void clang_annotateTokensImpl(void *UserData) {
4695 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4696 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4697 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4698 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4699 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4700
4701 // Determine the region of interest, which contains all of the tokens.
4702 SourceRange RegionOfInterest;
4703 RegionOfInterest.setBegin(
4704 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4705 RegionOfInterest.setEnd(
4706 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4707 Tokens[NumTokens-1])));
4708
4709 // A mapping from the source locations found when re-lexing or traversing the
4710 // region of interest to the corresponding cursors.
4711 AnnotateTokensData Annotated;
4712
4713 // Relex the tokens within the source range to look for preprocessing
4714 // directives.
4715 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4716 std::pair<FileID, unsigned> BeginLocInfo
4717 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4718 std::pair<FileID, unsigned> EndLocInfo
4719 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4720
4721 llvm::StringRef Buffer;
4722 bool Invalid = false;
4723 if (BeginLocInfo.first == EndLocInfo.first &&
4724 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4725 !Invalid) {
4726 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4727 CXXUnit->getASTContext().getLangOptions(),
4728 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4729 Buffer.end());
4730 Lex.SetCommentRetentionState(true);
4731
4732 // Lex tokens in raw mode until we hit the end of the range, to avoid
4733 // entering #includes or expanding macros.
4734 while (true) {
4735 Token Tok;
4736 Lex.LexFromRawLexer(Tok);
4737
4738 reprocess:
4739 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4740 // We have found a preprocessing directive. Gobble it up so that we
4741 // don't see it while preprocessing these tokens later, but keep track
4742 // of all of the token locations inside this preprocessing directive so
4743 // that we can annotate them appropriately.
4744 //
4745 // FIXME: Some simple tests here could identify macro definitions and
4746 // #undefs, to provide specific cursor kinds for those.
4747 llvm::SmallVector<SourceLocation, 32> Locations;
4748 do {
4749 Locations.push_back(Tok.getLocation());
4750 Lex.LexFromRawLexer(Tok);
4751 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4752
4753 using namespace cxcursor;
4754 CXCursor Cursor
4755 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4756 Locations.back()),
4757 TU);
4758 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4759 Annotated[Locations[I].getRawEncoding()] = Cursor;
4760 }
4761
4762 if (Tok.isAtStartOfLine())
4763 goto reprocess;
4764
4765 continue;
4766 }
4767
4768 if (Tok.is(tok::eof))
4769 break;
4770 }
4771 }
4772
4773 // Annotate all of the source locations in the region of interest that map to
4774 // a specific cursor.
4775 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4776 TU, RegionOfInterest);
4777
4778 // FIXME: We use a ridiculous stack size here because the data-recursion
4779 // algorithm uses a large stack frame than the non-data recursive version,
4780 // and AnnotationTokensWorker currently transforms the data-recursion
4781 // algorithm back into a traditional recursion by explicitly calling
4782 // VisitChildren(). We will need to remove this explicit recursive call.
4783 W.AnnotateTokens();
4784
4785 // If we ran into any entities that involve context-sensitive keywords,
4786 // take another pass through the tokens to mark them as such.
4787 if (W.hasContextSensitiveKeywords()) {
4788 for (unsigned I = 0; I != NumTokens; ++I) {
4789 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4790 continue;
4791
4792 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4793 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4794 if (ObjCPropertyDecl *Property
4795 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4796 if (Property->getPropertyAttributesAsWritten() != 0 &&
4797 llvm::StringSwitch<bool>(II->getName())
4798 .Case("readonly", true)
4799 .Case("assign", true)
4800 .Case("readwrite", true)
4801 .Case("retain", true)
4802 .Case("copy", true)
4803 .Case("nonatomic", true)
4804 .Case("atomic", true)
4805 .Case("getter", true)
4806 .Case("setter", true)
4807 .Default(false))
4808 Tokens[I].int_data[0] = CXToken_Keyword;
4809 }
4810 continue;
4811 }
4812
4813 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4814 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4815 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4816 if (llvm::StringSwitch<bool>(II->getName())
4817 .Case("in", true)
4818 .Case("out", true)
4819 .Case("inout", true)
4820 .Case("oneway", true)
4821 .Case("bycopy", true)
4822 .Case("byref", true)
4823 .Default(false))
4824 Tokens[I].int_data[0] = CXToken_Keyword;
4825 continue;
4826 }
4827
4828 if (Cursors[I].kind == CXCursor_CXXMethod) {
4829 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4830 if (CXXMethodDecl *Method
4831 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4832 if ((Method->hasAttr<FinalAttr>() ||
4833 Method->hasAttr<OverrideAttr>()) &&
4834 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4835 llvm::StringSwitch<bool>(II->getName())
4836 .Case("final", true)
4837 .Case("override", true)
4838 .Default(false))
4839 Tokens[I].int_data[0] = CXToken_Keyword;
4840 }
4841 continue;
4842 }
4843
4844 if (Cursors[I].kind == CXCursor_ClassDecl ||
4845 Cursors[I].kind == CXCursor_StructDecl ||
4846 Cursors[I].kind == CXCursor_ClassTemplate) {
4847 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4848 if (II->getName() == "final") {
4849 // We have to be careful with 'final', since it could be the name
4850 // of a member class rather than the context-sensitive keyword.
4851 // So, check whether the cursor associated with this
4852 Decl *D = getCursorDecl(Cursors[I]);
4853 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4854 if ((Record->hasAttr<FinalAttr>()) &&
4855 Record->getIdentifier() != II)
4856 Tokens[I].int_data[0] = CXToken_Keyword;
4857 } else if (ClassTemplateDecl *ClassTemplate
4858 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4859 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4860 if ((Record->hasAttr<FinalAttr>()) &&
4861 Record->getIdentifier() != II)
4862 Tokens[I].int_data[0] = CXToken_Keyword;
4863 }
4864 }
4865 continue;
4866 }
4867 }
4868 }
Ted Kremenekab979612010-11-11 08:05:23 +00004869}
4870
Ted Kremenek6db61092010-05-05 00:55:15 +00004871extern "C" {
4872
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004873void clang_annotateTokens(CXTranslationUnit TU,
4874 CXToken *Tokens, unsigned NumTokens,
4875 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004876
4877 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004878 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004879
Douglas Gregor4419b672010-10-21 06:10:04 +00004880 // Any token we don't specifically annotate will have a NULL cursor.
4881 CXCursor C = clang_getNullCursor();
4882 for (unsigned I = 0; I != NumTokens; ++I)
4883 Cursors[I] = C;
4884
Ted Kremeneka60ed472010-11-16 08:15:36 +00004885 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004886 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004887 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004888
Douglas Gregorbdf60622010-03-05 21:16:25 +00004889 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek6628a612011-03-18 22:51:30 +00004890
4891 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekab979612010-11-11 08:05:23 +00004892 llvm::CrashRecoveryContext CRC;
Ted Kremenek6628a612011-03-18 22:51:30 +00004893 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004894 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004895 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4896 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004897}
Ted Kremenek6628a612011-03-18 22:51:30 +00004898
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004899} // end: extern "C"
4900
4901//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004902// Operations for querying linkage of a cursor.
4903//===----------------------------------------------------------------------===//
4904
4905extern "C" {
4906CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004907 if (!clang_isDeclaration(cursor.kind))
4908 return CXLinkage_Invalid;
4909
Ted Kremenek16b42592010-03-03 06:36:57 +00004910 Decl *D = cxcursor::getCursorDecl(cursor);
4911 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4912 switch (ND->getLinkage()) {
4913 case NoLinkage: return CXLinkage_NoLinkage;
4914 case InternalLinkage: return CXLinkage_Internal;
4915 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4916 case ExternalLinkage: return CXLinkage_External;
4917 };
4918
4919 return CXLinkage_Invalid;
4920}
4921} // end: extern "C"
4922
4923//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004924// Operations for querying language of a cursor.
4925//===----------------------------------------------------------------------===//
4926
4927static CXLanguageKind getDeclLanguage(const Decl *D) {
4928 switch (D->getKind()) {
4929 default:
4930 break;
4931 case Decl::ImplicitParam:
4932 case Decl::ObjCAtDefsField:
4933 case Decl::ObjCCategory:
4934 case Decl::ObjCCategoryImpl:
4935 case Decl::ObjCClass:
4936 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004937 case Decl::ObjCForwardProtocol:
4938 case Decl::ObjCImplementation:
4939 case Decl::ObjCInterface:
4940 case Decl::ObjCIvar:
4941 case Decl::ObjCMethod:
4942 case Decl::ObjCProperty:
4943 case Decl::ObjCPropertyImpl:
4944 case Decl::ObjCProtocol:
4945 return CXLanguage_ObjC;
4946 case Decl::CXXConstructor:
4947 case Decl::CXXConversion:
4948 case Decl::CXXDestructor:
4949 case Decl::CXXMethod:
4950 case Decl::CXXRecord:
4951 case Decl::ClassTemplate:
4952 case Decl::ClassTemplatePartialSpecialization:
4953 case Decl::ClassTemplateSpecialization:
4954 case Decl::Friend:
4955 case Decl::FriendTemplate:
4956 case Decl::FunctionTemplate:
4957 case Decl::LinkageSpec:
4958 case Decl::Namespace:
4959 case Decl::NamespaceAlias:
4960 case Decl::NonTypeTemplateParm:
4961 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004962 case Decl::TemplateTemplateParm:
4963 case Decl::TemplateTypeParm:
4964 case Decl::UnresolvedUsingTypename:
4965 case Decl::UnresolvedUsingValue:
4966 case Decl::Using:
4967 case Decl::UsingDirective:
4968 case Decl::UsingShadow:
4969 return CXLanguage_CPlusPlus;
4970 }
4971
4972 return CXLanguage_C;
4973}
4974
4975extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004976
4977enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4978 if (clang_isDeclaration(cursor.kind))
4979 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004980 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregor58ddb602010-08-23 23:00:57 +00004981 return CXAvailability_Available;
4982
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004983 switch (D->getAvailability()) {
4984 case AR_Available:
4985 case AR_NotYetIntroduced:
4986 return CXAvailability_Available;
4987
4988 case AR_Deprecated:
Douglas Gregor58ddb602010-08-23 23:00:57 +00004989 return CXAvailability_Deprecated;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004990
4991 case AR_Unavailable:
4992 return CXAvailability_NotAvailable;
4993 }
Douglas Gregor58ddb602010-08-23 23:00:57 +00004994 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004995
Douglas Gregor58ddb602010-08-23 23:00:57 +00004996 return CXAvailability_Available;
4997}
4998
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004999CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5000 if (clang_isDeclaration(cursor.kind))
5001 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5002
5003 return CXLanguage_Invalid;
5004}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00005005
5006 /// \brief If the given cursor is the "templated" declaration
5007 /// descibing a class or function template, return the class or
5008 /// function template.
5009static Decl *maybeGetTemplateCursor(Decl *D) {
5010 if (!D)
5011 return 0;
5012
5013 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
5014 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5015 return FunTmpl;
5016
5017 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
5018 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5019 return ClassTmpl;
5020
5021 return D;
5022}
5023
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005024CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5025 if (clang_isDeclaration(cursor.kind)) {
5026 if (Decl *D = getCursorDecl(cursor)) {
5027 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00005028 if (!DC)
5029 return clang_getNullCursor();
5030
5031 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5032 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005033 }
5034 }
5035
5036 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
5037 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00005038 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005039 }
5040
5041 return clang_getNullCursor();
5042}
5043
5044CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5045 if (clang_isDeclaration(cursor.kind)) {
5046 if (Decl *D = getCursorDecl(cursor)) {
5047 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00005048 if (!DC)
5049 return clang_getNullCursor();
5050
5051 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5052 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005053 }
5054 }
5055
5056 // FIXME: Note that we can't easily compute the lexical context of a
5057 // statement or expression, so we return nothing.
5058 return clang_getNullCursor();
5059}
5060
Douglas Gregor9f592342010-10-01 20:25:15 +00005061static void CollectOverriddenMethods(DeclContext *Ctx,
5062 ObjCMethodDecl *Method,
5063 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5064 if (!Ctx)
5065 return;
5066
5067 // If we have a class or category implementation, jump straight to the
5068 // interface.
5069 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5070 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5071
5072 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5073 if (!Container)
5074 return;
5075
5076 // Check whether we have a matching method at this level.
5077 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5078 Method->isInstanceMethod()))
5079 if (Method != Overridden) {
5080 // We found an override at this level; there is no need to look
5081 // into other protocols or categories.
5082 Methods.push_back(Overridden);
5083 return;
5084 }
5085
5086 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5087 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5088 PEnd = Protocol->protocol_end();
5089 P != PEnd; ++P)
5090 CollectOverriddenMethods(*P, Method, Methods);
5091 }
5092
5093 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5094 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5095 PEnd = Category->protocol_end();
5096 P != PEnd; ++P)
5097 CollectOverriddenMethods(*P, Method, Methods);
5098 }
5099
5100 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5101 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5102 PEnd = Interface->protocol_end();
5103 P != PEnd; ++P)
5104 CollectOverriddenMethods(*P, Method, Methods);
5105
5106 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5107 Category; Category = Category->getNextClassCategory())
5108 CollectOverriddenMethods(Category, Method, Methods);
5109
5110 // We only look into the superclass if we haven't found anything yet.
5111 if (Methods.empty())
5112 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5113 return CollectOverriddenMethods(Super, Method, Methods);
5114 }
5115}
5116
5117void clang_getOverriddenCursors(CXCursor cursor,
5118 CXCursor **overridden,
5119 unsigned *num_overridden) {
5120 if (overridden)
5121 *overridden = 0;
5122 if (num_overridden)
5123 *num_overridden = 0;
5124 if (!overridden || !num_overridden)
5125 return;
5126
5127 if (!clang_isDeclaration(cursor.kind))
5128 return;
5129
5130 Decl *D = getCursorDecl(cursor);
5131 if (!D)
5132 return;
5133
5134 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00005135 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00005136 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5137 *num_overridden = CXXMethod->size_overridden_methods();
5138 if (!*num_overridden)
5139 return;
5140
5141 *overridden = new CXCursor [*num_overridden];
5142 unsigned I = 0;
5143 for (CXXMethodDecl::method_iterator
5144 M = CXXMethod->begin_overridden_methods(),
5145 MEnd = CXXMethod->end_overridden_methods();
5146 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005147 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005148 return;
5149 }
5150
5151 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5152 if (!Method)
5153 return;
5154
5155 // Handle Objective-C methods.
5156 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5157 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5158
5159 if (Methods.empty())
5160 return;
5161
5162 *num_overridden = Methods.size();
5163 *overridden = new CXCursor [Methods.size()];
5164 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005165 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005166}
5167
5168void clang_disposeOverriddenCursors(CXCursor *overridden) {
5169 delete [] overridden;
5170}
5171
Douglas Gregorecdcb882010-10-20 22:00:55 +00005172CXFile clang_getIncludedFile(CXCursor cursor) {
5173 if (cursor.kind != CXCursor_InclusionDirective)
5174 return 0;
5175
5176 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5177 return (void *)ID->getFile();
5178}
5179
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005180} // end: extern "C"
5181
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005182
5183//===----------------------------------------------------------------------===//
5184// C++ AST instrospection.
5185//===----------------------------------------------------------------------===//
5186
5187extern "C" {
5188unsigned clang_CXXMethod_isStatic(CXCursor C) {
5189 if (!clang_isDeclaration(C.kind))
5190 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005191
5192 CXXMethodDecl *Method = 0;
5193 Decl *D = cxcursor::getCursorDecl(C);
5194 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5195 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5196 else
5197 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5198 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005199}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005200
Douglas Gregor211924b2011-05-12 15:17:24 +00005201unsigned clang_CXXMethod_isVirtual(CXCursor C) {
5202 if (!clang_isDeclaration(C.kind))
5203 return 0;
5204
5205 CXXMethodDecl *Method = 0;
5206 Decl *D = cxcursor::getCursorDecl(C);
5207 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5208 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5209 else
5210 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5211 return (Method && Method->isVirtual()) ? 1 : 0;
5212}
5213
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005214} // end: extern "C"
5215
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005216//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005217// Attribute introspection.
5218//===----------------------------------------------------------------------===//
5219
5220extern "C" {
5221CXType clang_getIBOutletCollectionType(CXCursor C) {
5222 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005223 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005224
5225 IBOutletCollectionAttr *A =
5226 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5227
Douglas Gregor841b2382011-03-06 18:55:32 +00005228 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005229}
5230} // end: extern "C"
5231
5232//===----------------------------------------------------------------------===//
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005233// Inspecting memory usage.
5234//===----------------------------------------------------------------------===//
5235
Ted Kremenekf7870022011-04-20 16:41:07 +00005236typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005237
Ted Kremenekf7870022011-04-20 16:41:07 +00005238static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
5239 enum CXTUResourceUsageKind k,
Ted Kremenekba29bd22011-04-28 04:53:38 +00005240 unsigned long amount) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005241 CXTUResourceUsageEntry entry = { k, amount };
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005242 entries.push_back(entry);
5243}
5244
5245extern "C" {
5246
Ted Kremenekf7870022011-04-20 16:41:07 +00005247const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005248 const char *str = "";
5249 switch (kind) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005250 case CXTUResourceUsage_AST:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005251 str = "ASTContext: expressions, declarations, and types";
5252 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005253 case CXTUResourceUsage_Identifiers:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005254 str = "ASTContext: identifiers";
5255 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005256 case CXTUResourceUsage_Selectors:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005257 str = "ASTContext: selectors";
Ted Kremeneke294ab72011-04-19 04:36:17 +00005258 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005259 case CXTUResourceUsage_GlobalCompletionResults:
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005260 str = "Code completion: cached global results";
Ted Kremeneke294ab72011-04-19 04:36:17 +00005261 break;
Ted Kremenek457aaf02011-04-28 04:10:31 +00005262 case CXTUResourceUsage_SourceManagerContentCache:
5263 str = "SourceManager: content cache allocator";
5264 break;
Ted Kremenekba29bd22011-04-28 04:53:38 +00005265 case CXTUResourceUsage_AST_SideTables:
5266 str = "ASTContext: side tables";
5267 break;
Ted Kremenekf61b8312011-04-28 20:36:42 +00005268 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
5269 str = "SourceManager: malloc'ed memory buffers";
5270 break;
5271 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
5272 str = "SourceManager: mmap'ed memory buffers";
5273 break;
Ted Kremeneke9b5f3d2011-04-28 23:46:20 +00005274 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
5275 str = "ExternalASTSource: malloc'ed memory buffers";
5276 break;
5277 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
5278 str = "ExternalASTSource: mmap'ed memory buffers";
5279 break;
Ted Kremenek5e1db6a2011-05-04 01:38:46 +00005280 case CXTUResourceUsage_Preprocessor:
5281 str = "Preprocessor: malloc'ed memory";
5282 break;
5283 case CXTUResourceUsage_PreprocessingRecord:
5284 str = "Preprocessor: PreprocessingRecord";
5285 break;
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005286 }
5287 return str;
5288}
5289
Ted Kremenekf7870022011-04-20 16:41:07 +00005290CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005291 if (!TU) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005292 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005293 return usage;
5294 }
5295
5296 ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
5297 llvm::OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
5298 ASTContext &astContext = astUnit->getASTContext();
5299
5300 // How much memory is used by AST nodes and types?
Ted Kremenekf7870022011-04-20 16:41:07 +00005301 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
Ted Kremenekba29bd22011-04-28 04:53:38 +00005302 (unsigned long) astContext.getASTAllocatedMemory());
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005303
5304 // How much memory is used by identifiers?
Ted Kremenekf7870022011-04-20 16:41:07 +00005305 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005306 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
5307
5308 // How much memory is used for selectors?
Ted Kremenekf7870022011-04-20 16:41:07 +00005309 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005310 (unsigned long) astContext.Selectors.getTotalMemory());
5311
Ted Kremenekba29bd22011-04-28 04:53:38 +00005312 // How much memory is used by ASTContext's side tables?
5313 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
5314 (unsigned long) astContext.getSideTableAllocatedMemory());
5315
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005316 // How much memory is used for caching global code completion results?
5317 unsigned long completionBytes = 0;
5318 if (GlobalCodeCompletionAllocator *completionAllocator =
5319 astUnit->getCachedCompletionAllocator().getPtr()) {
Ted Kremenek5e1db6a2011-05-04 01:38:46 +00005320 completionBytes = completionAllocator->getTotalMemory();
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005321 }
Ted Kremenek457aaf02011-04-28 04:10:31 +00005322 createCXTUResourceUsageEntry(*entries,
5323 CXTUResourceUsage_GlobalCompletionResults,
5324 completionBytes);
5325
5326 // How much memory is being used by SourceManager's content cache?
5327 createCXTUResourceUsageEntry(*entries,
5328 CXTUResourceUsage_SourceManagerContentCache,
5329 (unsigned long) astContext.getSourceManager().getContentCacheSize());
Ted Kremenekf61b8312011-04-28 20:36:42 +00005330
5331 // How much memory is being used by the MemoryBuffer's in SourceManager?
5332 const SourceManager::MemoryBufferSizes &srcBufs =
5333 astUnit->getSourceManager().getMemoryBufferSizes();
5334
5335 createCXTUResourceUsageEntry(*entries,
5336 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
5337 (unsigned long) srcBufs.malloc_bytes);
Ted Kremeneke9b5f3d2011-04-28 23:46:20 +00005338 createCXTUResourceUsageEntry(*entries,
Ted Kremenekf61b8312011-04-28 20:36:42 +00005339 CXTUResourceUsage_SourceManager_Membuffer_MMap,
5340 (unsigned long) srcBufs.mmap_bytes);
Ted Kremeneke9b5f3d2011-04-28 23:46:20 +00005341
5342 // How much memory is being used by the ExternalASTSource?
5343 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
5344 const ExternalASTSource::MemoryBufferSizes &sizes =
5345 esrc->getMemoryBufferSizes();
5346
5347 createCXTUResourceUsageEntry(*entries,
5348 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
5349 (unsigned long) sizes.malloc_bytes);
5350 createCXTUResourceUsageEntry(*entries,
5351 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
5352 (unsigned long) sizes.mmap_bytes);
5353 }
Ted Kremenek5e1db6a2011-05-04 01:38:46 +00005354
5355 // How much memory is being used by the Preprocessor?
5356 Preprocessor &pp = astUnit->getPreprocessor();
5357 const llvm::BumpPtrAllocator &ppAlloc = pp.getPreprocessorAllocator();
5358 createCXTUResourceUsageEntry(*entries,
5359 CXTUResourceUsage_Preprocessor,
5360 ppAlloc.getTotalMemory());
5361
5362 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
5363 createCXTUResourceUsageEntry(*entries,
5364 CXTUResourceUsage_PreprocessingRecord,
5365 pRec->getTotalMemory());
5366 }
5367
5368
Ted Kremenekf7870022011-04-20 16:41:07 +00005369 CXTUResourceUsage usage = { (void*) entries.get(),
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005370 (unsigned) entries->size(),
5371 entries->size() ? &(*entries)[0] : 0 };
5372 entries.take();
5373 return usage;
5374}
5375
Ted Kremenekf7870022011-04-20 16:41:07 +00005376void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005377 if (usage.data)
5378 delete (MemUsageEntries*) usage.data;
5379}
5380
5381} // end extern "C"
5382
Douglas Gregor6df78732011-05-05 20:27:22 +00005383void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
5384 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
5385 for (unsigned I = 0; I != Usage.numEntries; ++I)
5386 fprintf(stderr, " %s: %lu\n",
5387 clang_getTUResourceUsageName(Usage.entries[I].kind),
5388 Usage.entries[I].amount);
5389
5390 clang_disposeCXTUResourceUsage(Usage);
5391}
5392
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005393//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005394// Misc. utility functions.
5395//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005396
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005397/// Default to using an 8 MB stack size on "safety" threads.
5398static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005399
5400namespace clang {
5401
5402bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005403 void (*Fn)(void*), void *UserData,
5404 unsigned Size) {
5405 if (!Size)
5406 Size = GetSafetyThreadStackSize();
5407 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005408 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5409 return CRC.RunSafely(Fn, UserData);
5410}
5411
5412unsigned GetSafetyThreadStackSize() {
5413 return SafetyStackThreadSize;
5414}
5415
5416void SetSafetyThreadStackSize(unsigned Value) {
5417 SafetyStackThreadSize = Value;
5418}
5419
5420}
5421
Ted Kremenek04bb7162010-01-22 22:44:15 +00005422extern "C" {
5423
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005424CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005425 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005426}
5427
5428} // end: extern "C"
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005429