blob: 26e4af4049148f0aeaf80f8a8ce74b5eaf6805dc [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"
Benjamin Kramerb846deb2010-04-12 19:45:50 +000033#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregor33e9abd2010-01-22 19:49:59 +000034#include "clang/Lex/Preprocessor.h"
Douglas Gregora67e03f2010-09-09 21:42:20 +000035#include "llvm/ADT/STLExtras.h"
Ted Kremenekd8c370c2010-11-02 23:10:24 +000036#include "llvm/ADT/Optional.h"
Douglas Gregorf5251602011-03-08 17:10:18 +000037#include "llvm/ADT/StringSwitch.h"
Ted Kremenekd8c370c2010-11-02 23:10:24 +000038#include "clang/Analysis/Support/SaveAndRestore.h"
Daniel Dunbarc7df4f32010-08-18 18:43:14 +000039#include "llvm/Support/CrashRecoveryContext.h"
Daniel Dunbar48615ff2010-10-08 19:30:33 +000040#include "llvm/Support/PrettyStackTrace.h"
Douglas Gregor02465752009-10-16 21:24:31 +000041#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor358559d2010-10-02 22:49:11 +000042#include "llvm/Support/raw_ostream.h"
Douglas Gregor7a07fcb2010-08-09 21:00:09 +000043#include "llvm/Support/Timer.h"
Michael J. Spencer03013fa2010-11-29 18:12:39 +000044#include "llvm/Support/Mutex.h"
45#include "llvm/Support/Program.h"
46#include "llvm/Support/Signals.h"
47#include "llvm/Support/Threading.h"
Ted Kremenek37f1ea02010-11-15 23:11:54 +000048#include "llvm/Support/Compiler.h"
Ted Kremenekfc062212009-10-19 21:44:57 +000049
Steve Naroff50398192009-08-28 15:28:48 +000050using namespace clang;
Ted Kremenek16c440a2010-01-15 20:35:54 +000051using namespace clang::cxcursor;
Ted Kremenekee4db4f2010-02-17 00:41:08 +000052using namespace clang::cxstring;
Steve Naroff50398192009-08-28 15:28:48 +000053
Ted Kremeneka60ed472010-11-16 08:15:36 +000054static CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) {
55 if (!TU)
56 return 0;
57 CXTranslationUnit D = new CXTranslationUnitImpl();
58 D->TUData = TU;
59 D->StringPool = createCXStringPool();
60 return D;
61}
62
Douglas Gregor33e9abd2010-01-22 19:49:59 +000063/// \brief The result of comparing two source ranges.
64enum RangeComparisonResult {
65 /// \brief Either the ranges overlap or one of the ranges is invalid.
66 RangeOverlap,
Ted Kremenekf0e23e82010-02-17 00:41:40 +000067
Douglas Gregor33e9abd2010-01-22 19:49:59 +000068 /// \brief The first range ends before the second range starts.
69 RangeBefore,
Ted Kremenekf0e23e82010-02-17 00:41:40 +000070
Douglas Gregor33e9abd2010-01-22 19:49:59 +000071 /// \brief The first range starts after the second range ends.
72 RangeAfter
73};
74
Ted Kremenekf0e23e82010-02-17 00:41:40 +000075/// \brief Compare two source ranges to determine their relative position in
Douglas Gregor33e9abd2010-01-22 19:49:59 +000076/// the translation unit.
Ted Kremenekf0e23e82010-02-17 00:41:40 +000077static RangeComparisonResult RangeCompare(SourceManager &SM,
78 SourceRange R1,
Douglas Gregor33e9abd2010-01-22 19:49:59 +000079 SourceRange R2) {
80 assert(R1.isValid() && "First range is invalid?");
81 assert(R2.isValid() && "Second range is invalid?");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000082 if (R1.getEnd() != R2.getBegin() &&
Daniel Dunbard52864b2010-02-14 10:02:57 +000083 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
Douglas Gregor33e9abd2010-01-22 19:49:59 +000084 return RangeBefore;
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000085 if (R2.getEnd() != R1.getBegin() &&
Daniel Dunbard52864b2010-02-14 10:02:57 +000086 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
Douglas Gregor33e9abd2010-01-22 19:49:59 +000087 return RangeAfter;
88 return RangeOverlap;
89}
90
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000091/// \brief Determine if a source location falls within, before, or after a
92/// a given source range.
93static RangeComparisonResult LocationCompare(SourceManager &SM,
94 SourceLocation L, SourceRange R) {
95 assert(R.isValid() && "First range is invalid?");
96 assert(L.isValid() && "Second range is invalid?");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000097 if (L == R.getBegin() || L == R.getEnd())
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000098 return RangeOverlap;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000099 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
100 return RangeBefore;
101 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
102 return RangeAfter;
103 return RangeOverlap;
104}
105
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000106/// \brief Translate a Clang source range into a CIndex source range.
107///
108/// Clang internally represents ranges where the end location points to the
109/// start of the token at the end. However, for external clients it is more
110/// useful to have a CXSourceRange be a proper half-open interval. This routine
111/// does the appropriate translation.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000112CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000113 const LangOptions &LangOpts,
Chris Lattner0a76aae2010-06-18 22:45:06 +0000114 const CharSourceRange &R) {
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000115 // We want the last character in this location, so we will adjust the
Douglas Gregor6a5a23f2010-03-19 21:51:54 +0000116 // location accordingly.
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000117 SourceLocation EndLoc = R.getEnd();
Douglas Gregora9b06d42010-11-09 06:24:54 +0000118 if (EndLoc.isValid() && EndLoc.isMacroID())
Douglas Gregorffcd9852011-04-20 21:16:21 +0000119 EndLoc = SM.getInstantiationRange(EndLoc).second;
Chris Lattner0a76aae2010-06-18 22:45:06 +0000120 if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +0000121 unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000122 EndLoc = EndLoc.getFileLocWithOffset(Length);
123 }
124
125 CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
126 R.getBegin().getRawEncoding(),
127 EndLoc.getRawEncoding() };
128 return Result;
129}
Douglas Gregor1db19de2010-01-19 21:36:55 +0000130
Ted Kremenek8a8da7d2010-01-06 03:42:32 +0000131//===----------------------------------------------------------------------===//
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000132// Cursor visitor.
Ted Kremenek8a8da7d2010-01-06 03:42:32 +0000133//===----------------------------------------------------------------------===//
134
Steve Naroff89922f82009-08-31 00:59:03 +0000135namespace {
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000136
137class VisitorJob {
138public:
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000139 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
Ted Kremeneke4979cc2010-11-13 00:58:18 +0000140 TypeLocVisitKind, OverloadExprPartsKind,
Ted Kremenek60608ec2010-11-17 00:50:47 +0000141 DeclRefExprPartsKind, LabelRefVisitKind,
Ted Kremenekf64d8032010-11-18 00:02:32 +0000142 ExplicitTemplateArgsVisitKind,
143 NestedNameSpecifierVisitKind,
Douglas Gregorf3db29f2011-02-25 18:19:59 +0000144 NestedNameSpecifierLocVisitKind,
Ted Kremenekcdba6592010-11-18 00:42:18 +0000145 DeclarationNameInfoVisitKind,
Douglas Gregor94d96292011-01-19 20:34:17 +0000146 MemberRefVisitKind, SizeOfPackExprPartsKind };
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000147protected:
Ted Kremenekf64d8032010-11-18 00:02:32 +0000148 void *data[3];
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000149 CXCursor parent;
150 Kind K;
Ted Kremenekf64d8032010-11-18 00:02:32 +0000151 VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
152 : parent(C), K(k) {
153 data[0] = d1;
154 data[1] = d2;
155 data[2] = d3;
156 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000157public:
158 Kind getKind() const { return K; }
159 const CXCursor &getParent() const { return parent; }
160 static bool classof(VisitorJob *VJ) { return true; }
161};
162
163typedef llvm::SmallVector<VisitorJob, 10> VisitorWorkList;
164
Douglas Gregorb1373d02010-01-20 20:59:29 +0000165// Cursor visitor.
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000166class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
Ted Kremenekcdba6592010-11-18 00:42:18 +0000167 public TypeLocVisitor<CursorVisitor, bool>
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000168{
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000169 /// \brief The translation unit we are traversing.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000170 CXTranslationUnit TU;
171 ASTUnit *AU;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000172
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000173 /// \brief The parent cursor whose children we are traversing.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000174 CXCursor Parent;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000175
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000176 /// \brief The declaration that serves at the parent of any statement or
177 /// expression nodes.
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000178 Decl *StmtParent;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000179
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000180 /// \brief The visitor function.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000181 CXCursorVisitor Visitor;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000182
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000183 /// \brief The opaque client data, to be passed along to the visitor.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000184 CXClientData ClientData;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000185
Douglas Gregor7d1d49d2009-10-16 20:01:17 +0000186 // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
187 // to the visitor. Declarations with a PCH level greater than this value will
188 // be suppressed.
189 unsigned MaxPCHLevel;
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000190
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000191 /// \brief Whether we should visit the preprocessing record entries last,
192 /// after visiting other declarations.
193 bool VisitPreprocessorLast;
194
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000195 /// \brief When valid, a source range to which the cursor should restrict
196 /// its search.
197 SourceRange RegionOfInterest;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000198
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000199 // FIXME: Eventually remove. This part of a hack to support proper
200 // iteration over all Decls contained lexically within an ObjC container.
201 DeclContext::decl_iterator *DI_current;
202 DeclContext::decl_iterator DE_current;
203
Ted Kremenekd1ded662010-11-15 23:31:32 +0000204 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
205 llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
206 llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
207
Douglas Gregorb1373d02010-01-20 20:59:29 +0000208 using DeclVisitor<CursorVisitor, bool>::Visit;
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000209 using TypeLocVisitor<CursorVisitor, bool>::Visit;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000210
211 /// \brief Determine whether this particular source range comes before, comes
212 /// after, or overlaps the region of interest.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000213 ///
Daniel Dunbard52864b2010-02-14 10:02:57 +0000214 /// \param R a half-open source range retrieved from the abstract syntax tree.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000215 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
216
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000217 class SetParentRAII {
218 CXCursor &Parent;
219 Decl *&StmtParent;
220 CXCursor OldParent;
221
222 public:
223 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
224 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
225 {
226 Parent = NewParent;
227 if (clang_isDeclaration(Parent.kind))
228 StmtParent = getCursorDecl(Parent);
229 }
230
231 ~SetParentRAII() {
232 Parent = OldParent;
233 if (clang_isDeclaration(Parent.kind))
234 StmtParent = getCursorDecl(Parent);
235 }
236 };
237
Steve Naroff89922f82009-08-31 00:59:03 +0000238public:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000239 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
240 CXClientData ClientData,
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000241 unsigned MaxPCHLevel,
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000242 bool VisitPreprocessorLast,
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000243 SourceRange RegionOfInterest = SourceRange())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000244 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
245 Visitor(Visitor), ClientData(ClientData),
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000246 MaxPCHLevel(MaxPCHLevel), VisitPreprocessorLast(VisitPreprocessorLast),
247 RegionOfInterest(RegionOfInterest), DI_current(0)
Douglas Gregorb1373d02010-01-20 20:59:29 +0000248 {
249 Parent.kind = CXCursor_NoDeclFound;
250 Parent.data[0] = 0;
251 Parent.data[1] = 0;
252 Parent.data[2] = 0;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000253 StmtParent = 0;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000254 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000255
Ted Kremenekd1ded662010-11-15 23:31:32 +0000256 ~CursorVisitor() {
257 // Free the pre-allocated worklists for data-recursion.
258 for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
259 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
260 delete *I;
261 }
262 }
263
Ted Kremeneka60ed472010-11-16 08:15:36 +0000264 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
265 CXTranslationUnit getTU() const { return TU; }
Ted Kremenekab979612010-11-11 08:05:23 +0000266
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000267 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000268
269 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
270 getPreprocessedEntities();
271
Douglas Gregorb1373d02010-01-20 20:59:29 +0000272 bool VisitChildren(CXCursor Parent);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000273
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000274 // Declaration visitors
Richard Smith162e1c12011-04-15 14:24:37 +0000275 bool VisitTypeAliasDecl(TypeAliasDecl *D);
Ted Kremenek09dfa372010-02-18 05:46:33 +0000276 bool VisitAttributes(Decl *D);
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000277 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenek3064ef92010-08-27 21:34:58 +0000278 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000279 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000280 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000281 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
282 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000283 bool VisitTagDecl(TagDecl *D);
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000284 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregor74dbe642010-08-31 19:31:58 +0000285 bool VisitClassTemplatePartialSpecializationDecl(
286 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000287 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000288 bool VisitEnumConstantDecl(EnumConstantDecl *D);
289 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
290 bool VisitFunctionDecl(FunctionDecl *ND);
291 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000292 bool VisitVarDecl(VarDecl *);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000293 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000294 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor39d6f072010-08-31 19:02:00 +0000295 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000296 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000297 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
298 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
299 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
300 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek23173d72010-05-18 21:09:07 +0000301 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremenek79758f62010-02-18 22:36:18 +0000302 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
303 bool VisitObjCImplDecl(ObjCImplDecl *D);
304 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
305 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000306 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
307 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
308 bool VisitObjCClassDecl(ObjCClassDecl *D);
Douglas Gregora4ffd852010-11-17 01:03:52 +0000309 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
Ted Kremeneka0536d82010-05-07 01:04:29 +0000310 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenek8f06e0e2010-05-06 23:38:21 +0000311 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregor69319002010-08-31 23:48:11 +0000312 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000313 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregor7e242562010-09-01 19:52:22 +0000314 bool VisitUsingDecl(UsingDecl *D);
315 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
316 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000317
Douglas Gregor01829d32010-08-31 14:41:23 +0000318 // Name visitor
319 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000320 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregordc355712011-02-25 00:36:19 +0000321 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
Douglas Gregor01829d32010-08-31 14:41:23 +0000322
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000323 // Template visitors
324 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregor0b36e612010-08-31 20:37:03 +0000325 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000326 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
327
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000328 // Type visitors
Douglas Gregor01829d32010-08-31 14:41:23 +0000329 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000330 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000331 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000332 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
333 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000334 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000335 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCallc12c5bb2010-05-15 11:32:37 +0000336 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000337 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
Abramo Bagnara075f8f12010-12-10 16:29:40 +0000338 bool VisitParenTypeLoc(ParenTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000339 bool VisitPointerTypeLoc(PointerTypeLoc TL);
340 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
341 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
342 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
343 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor01829d32010-08-31 14:41:23 +0000344 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000345 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000346 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000347 // FIXME: Implement visitors here when the unimplemented TypeLocs get
348 // implemented
349 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
Douglas Gregor7536dd52010-12-20 02:24:11 +0000350 bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000351 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000352 bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
Douglas Gregor94fdffa2011-03-01 20:11:18 +0000353 bool VisitDependentTemplateSpecializationTypeLoc(
354 DependentTemplateSpecializationTypeLoc TL);
Douglas Gregor9e876872011-03-01 18:12:44 +0000355 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000356
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000357 // Data-recursive visitor functions.
358 bool IsInRegionOfInterest(CXCursor C);
359 bool RunVisitorWorkList(VisitorWorkList &WL);
360 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
Ted Kremenekcdba6592010-11-18 00:42:18 +0000361 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
Steve Naroff89922f82009-08-31 00:59:03 +0000362};
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000363
Ted Kremenekab188932010-01-05 19:32:54 +0000364} // end anonymous namespace
Benjamin Kramer5e4bc592009-10-18 16:11:04 +0000365
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000366static SourceRange getRawCursorExtent(CXCursor C);
Douglas Gregor66537982010-11-17 17:14:07 +0000367static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
368
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000369
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000370RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000371 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000372}
373
Douglas Gregorb1373d02010-01-20 20:59:29 +0000374/// \brief Visit the given cursor and, if requested by the visitor,
375/// its children.
376///
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000377/// \param Cursor the cursor to visit.
378///
379/// \param CheckRegionOfInterest if true, then the caller already checked that
380/// this cursor is within the region of interest.
381///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000382/// \returns true if the visitation should be aborted, false if it
383/// should continue.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000384bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregorb1373d02010-01-20 20:59:29 +0000385 if (clang_isInvalid(Cursor.kind))
386 return false;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000387
Douglas Gregorb1373d02010-01-20 20:59:29 +0000388 if (clang_isDeclaration(Cursor.kind)) {
389 Decl *D = getCursorDecl(Cursor);
390 assert(D && "Invalid declaration cursor");
391 if (D->getPCHLevel() > MaxPCHLevel)
392 return false;
393
394 if (D->isImplicit())
395 return false;
396 }
397
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000398 // If we have a range of interest, and this cursor doesn't intersect with it,
399 // we're done.
400 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000401 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbarf408f322010-02-14 08:32:05 +0000402 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000403 return false;
404 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000405
Douglas Gregorb1373d02010-01-20 20:59:29 +0000406 switch (Visitor(Cursor, Parent, ClientData)) {
407 case CXChildVisit_Break:
408 return true;
409
410 case CXChildVisit_Continue:
411 return false;
412
413 case CXChildVisit_Recurse:
414 return VisitChildren(Cursor);
415 }
416
Douglas Gregorfd643772010-01-25 16:45:46 +0000417 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000418}
419
Douglas Gregor788f5a12010-03-20 00:41:21 +0000420std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
421CursorVisitor::getPreprocessedEntities() {
422 PreprocessingRecord &PPRec
Ted Kremeneka60ed472010-11-16 08:15:36 +0000423 = *AU->getPreprocessor().getPreprocessingRecord();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000424
425 bool OnlyLocalDecls
Douglas Gregor32038bb2010-12-21 19:07:48 +0000426 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
427
428 if (OnlyLocalDecls && RegionOfInterest.isValid()) {
429 // If we would only look at local declarations but we have a region of
430 // interest, check whether that region of interest is in the main file.
431 // If not, we should traverse all declarations.
432 // FIXME: My kingdom for a proper binary search approach to finding
433 // cursors!
434 std::pair<FileID, unsigned> Location
435 = AU->getSourceManager().getDecomposedInstantiationLoc(
436 RegionOfInterest.getBegin());
437 if (Location.first != AU->getSourceManager().getMainFileID())
438 OnlyLocalDecls = false;
439 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000440
Douglas Gregor89d99802010-11-30 06:16:57 +0000441 PreprocessingRecord::iterator StartEntity, EndEntity;
442 if (OnlyLocalDecls) {
443 StartEntity = AU->pp_entity_begin();
444 EndEntity = AU->pp_entity_end();
445 } else {
446 StartEntity = PPRec.begin();
447 EndEntity = PPRec.end();
448 }
449
Douglas Gregor788f5a12010-03-20 00:41:21 +0000450 // There is no region of interest; we have to walk everything.
451 if (RegionOfInterest.isInvalid())
Douglas Gregor89d99802010-11-30 06:16:57 +0000452 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000453
454 // Find the file in which the region of interest lands.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000455 SourceManager &SM = AU->getSourceManager();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000456 std::pair<FileID, unsigned> Begin
457 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
458 std::pair<FileID, unsigned> End
459 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
460
461 // The region of interest spans files; we have to walk everything.
462 if (Begin.first != End.first)
Douglas Gregor89d99802010-11-30 06:16:57 +0000463 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000464
465 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
Ted Kremeneka60ed472010-11-16 08:15:36 +0000466 = AU->getPreprocessedEntitiesByFile();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000467 if (ByFileMap.empty()) {
468 // Build the mapping from files to sets of preprocessed entities.
Douglas Gregor89d99802010-11-30 06:16:57 +0000469 for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
Douglas Gregor788f5a12010-03-20 00:41:21 +0000470 std::pair<FileID, unsigned> P
471 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
Douglas Gregor89d99802010-11-30 06:16:57 +0000472
Douglas Gregor788f5a12010-03-20 00:41:21 +0000473 ByFileMap[P.first].push_back(*E);
474 }
475 }
476
477 return std::make_pair(ByFileMap[Begin.first].begin(),
478 ByFileMap[Begin.first].end());
479}
480
Douglas Gregorb1373d02010-01-20 20:59:29 +0000481/// \brief Visit the children of the given cursor.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000482///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000483/// \returns true if the visitation should be aborted, false if it
484/// should continue.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000485bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregorc314aa42011-03-02 19:17:03 +0000486 if (clang_isReference(Cursor.kind) &&
487 Cursor.kind != CXCursor_CXXBaseSpecifier) {
Douglas Gregora59e3902010-01-21 23:27:09 +0000488 // By definition, references have no children.
489 return false;
490 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000491
492 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregorb1373d02010-01-20 20:59:29 +0000493 // done.
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000494 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000495
Douglas Gregorb1373d02010-01-20 20:59:29 +0000496 if (clang_isDeclaration(Cursor.kind)) {
497 Decl *D = getCursorDecl(Cursor);
Douglas Gregor06d9b1a2011-04-14 21:41:34 +0000498 if (!D)
499 return false;
500
Ted Kremenek539311e2010-02-18 18:47:01 +0000501 return VisitAttributes(D) || Visit(D);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000502 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000503
Douglas Gregor06d9b1a2011-04-14 21:41:34 +0000504 if (clang_isStatement(Cursor.kind)) {
505 if (Stmt *S = getCursorStmt(Cursor))
506 return Visit(S);
507
508 return false;
509 }
510
511 if (clang_isExpression(Cursor.kind)) {
512 if (Expr *E = getCursorExpr(Cursor))
513 return Visit(E);
514
515 return false;
516 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000517
Douglas Gregorb1373d02010-01-20 20:59:29 +0000518 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000519 CXTranslationUnit tu = getCursorTU(Cursor);
520 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000521
522 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
523 for (unsigned I = 0; I != 2; ++I) {
524 if (VisitOrder[I]) {
525 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
526 RegionOfInterest.isInvalid()) {
527 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
528 TLEnd = CXXUnit->top_level_end();
529 TL != TLEnd; ++TL) {
530 if (Visit(MakeCXCursor(*TL, tu), true))
531 return true;
532 }
533 } else if (VisitDeclContext(
534 CXXUnit->getASTContext().getTranslationUnitDecl()))
Douglas Gregor7b691f332010-01-20 21:13:59 +0000535 return true;
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000536 continue;
Douglas Gregor7b691f332010-01-20 21:13:59 +0000537 }
Bob Wilson3178cb62010-03-19 03:57:57 +0000538
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000539 // Walk the preprocessing record.
540 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
541 // FIXME: Once we have the ability to deserialize a preprocessing record,
542 // do so.
543 PreprocessingRecord::iterator E, EEnd;
544 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
545 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
546 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
547 return true;
548
549 continue;
550 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000551
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000552 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
553 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
554 return true;
555
556 continue;
557 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000558
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000559 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
560 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
561 return true;
562
563 continue;
564 }
Douglas Gregorecdcb882010-10-20 22:00:55 +0000565 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000566 }
567 }
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000568
Douglas Gregor7b691f332010-01-20 21:13:59 +0000569 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000570 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000571
Douglas Gregorc314aa42011-03-02 19:17:03 +0000572 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
573 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
574 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
575 return Visit(BaseTSInfo->getTypeLoc());
576 }
577 }
578 }
579
Douglas Gregorb1373d02010-01-20 20:59:29 +0000580 // Nothing to visit at the moment.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000581 return false;
582}
583
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000584bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
Douglas Gregor13c8ccb2011-04-22 23:49:24 +0000585 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
586 if (Visit(TSInfo->getTypeLoc()))
587 return true;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000588
Ted Kremenek664cffd2010-07-22 11:30:19 +0000589 if (Stmt *Body = B->getBody())
590 return Visit(MakeCXCursor(Body, StmtParent, TU));
591
592 return false;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000593}
594
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000595llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
596 if (RegionOfInterest.isValid()) {
Douglas Gregor66537982010-11-17 17:14:07 +0000597 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000598 if (Range.isInvalid())
599 return llvm::Optional<bool>();
Douglas Gregor66537982010-11-17 17:14:07 +0000600
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000601 switch (CompareRegionOfInterest(Range)) {
602 case RangeBefore:
603 // This declaration comes before the region of interest; skip it.
604 return llvm::Optional<bool>();
605
606 case RangeAfter:
607 // This declaration comes after the region of interest; we're done.
608 return false;
609
610 case RangeOverlap:
611 // This declaration overlaps the region of interest; visit it.
612 break;
613 }
614 }
615 return true;
616}
617
618bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
619 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
620
621 // FIXME: Eventually remove. This part of a hack to support proper
622 // iteration over all Decls contained lexically within an ObjC container.
623 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
624 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
625
626 for ( ; I != E; ++I) {
Ted Kremenek23173d72010-05-18 21:09:07 +0000627 Decl *D = *I;
628 if (D->getLexicalDeclContext() != DC)
629 continue;
Ted Kremenek23173d72010-05-18 21:09:07 +0000630 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000631 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
632 if (!V.hasValue())
633 continue;
634 if (!V.getValue())
635 return false;
Daniel Dunbard52864b2010-02-14 10:02:57 +0000636 if (Visit(Cursor, true))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000637 return true;
638 }
Douglas Gregorb1373d02010-01-20 20:59:29 +0000639 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000640}
641
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000642bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
643 llvm_unreachable("Translation units are visited directly by Visit()");
644 return false;
645}
646
Richard Smith162e1c12011-04-15 14:24:37 +0000647bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
648 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
649 return Visit(TSInfo->getTypeLoc());
650
651 return false;
652}
653
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000654bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
655 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
656 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000657
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000658 return false;
659}
660
661bool CursorVisitor::VisitTagDecl(TagDecl *D) {
662 return VisitDeclContext(D);
663}
664
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000665bool CursorVisitor::VisitClassTemplateSpecializationDecl(
666 ClassTemplateSpecializationDecl *D) {
667 bool ShouldVisitBody = false;
668 switch (D->getSpecializationKind()) {
669 case TSK_Undeclared:
670 case TSK_ImplicitInstantiation:
671 // Nothing to visit
672 return false;
673
674 case TSK_ExplicitInstantiationDeclaration:
675 case TSK_ExplicitInstantiationDefinition:
676 break;
677
678 case TSK_ExplicitSpecialization:
679 ShouldVisitBody = true;
680 break;
681 }
682
683 // Visit the template arguments used in the specialization.
684 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
685 TypeLoc TL = SpecType->getTypeLoc();
686 if (TemplateSpecializationTypeLoc *TSTLoc
687 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
688 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
689 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
690 return true;
691 }
692 }
693
694 if (ShouldVisitBody && VisitCXXRecordDecl(D))
695 return true;
696
697 return false;
698}
699
Douglas Gregor74dbe642010-08-31 19:31:58 +0000700bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
701 ClassTemplatePartialSpecializationDecl *D) {
702 // FIXME: Visit the "outer" template parameter lists on the TagDecl
703 // before visiting these template parameters.
704 if (VisitTemplateParameters(D->getTemplateParameters()))
705 return true;
706
707 // Visit the partial specialization arguments.
708 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
709 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
710 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
711 return true;
712
713 return VisitCXXRecordDecl(D);
714}
715
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000716bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor84b51d72010-09-01 20:16:53 +0000717 // Visit the default argument.
718 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
719 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
720 if (Visit(DefArg->getTypeLoc()))
721 return true;
722
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000723 return false;
724}
725
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000726bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
727 if (Expr *Init = D->getInitExpr())
728 return Visit(MakeCXCursor(Init, StmtParent, TU));
729 return false;
730}
731
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000732bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
733 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
734 if (Visit(TSInfo->getTypeLoc()))
735 return true;
736
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000737 // Visit the nested-name-specifier, if present.
738 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
739 if (VisitNestedNameSpecifierLoc(QualifierLoc))
740 return true;
741
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000742 return false;
743}
744
Douglas Gregora67e03f2010-09-09 21:42:20 +0000745/// \brief Compare two base or member initializers based on their source order.
Sean Huntcbb67482011-01-08 20:30:50 +0000746static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
747 CXXCtorInitializer const * const *X
748 = static_cast<CXXCtorInitializer const * const *>(Xp);
749 CXXCtorInitializer const * const *Y
750 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000751
752 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
753 return -1;
754 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
755 return 1;
756 else
757 return 0;
758}
759
Douglas Gregorb1373d02010-01-20 20:59:29 +0000760bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor01829d32010-08-31 14:41:23 +0000761 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
762 // Visit the function declaration's syntactic components in the order
763 // written. This requires a bit of work.
Abramo Bagnara723df242010-12-14 22:11:44 +0000764 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor01829d32010-08-31 14:41:23 +0000765 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
766
767 // If we have a function declared directly (without the use of a typedef),
768 // visit just the return type. Otherwise, just visit the function's type
769 // now.
770 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
771 (!FTL && Visit(TL)))
772 return true;
773
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000774 // Visit the nested-name-specifier, if present.
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000775 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
776 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000777 return true;
Douglas Gregor01829d32010-08-31 14:41:23 +0000778
779 // Visit the declaration name.
780 if (VisitDeclarationNameInfo(ND->getNameInfo()))
781 return true;
782
783 // FIXME: Visit explicitly-specified template arguments!
784
785 // Visit the function parameters, if we have a function type.
786 if (FTL && VisitFunctionTypeLoc(*FTL, true))
787 return true;
788
789 // FIXME: Attributes?
790 }
791
Francois Pichet8387e2a2011-04-22 22:18:13 +0000792 if (ND->isThisDeclarationADefinition() && !ND->isLateTemplateParsed()) {
Douglas Gregora67e03f2010-09-09 21:42:20 +0000793 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
794 // Find the initializers that were written in the source.
Sean Huntcbb67482011-01-08 20:30:50 +0000795 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregora67e03f2010-09-09 21:42:20 +0000796 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
797 IEnd = Constructor->init_end();
798 I != IEnd; ++I) {
799 if (!(*I)->isWritten())
800 continue;
801
802 WrittenInits.push_back(*I);
803 }
804
805 // Sort the initializers in source order
806 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Sean Huntcbb67482011-01-08 20:30:50 +0000807 &CompareCXXCtorInitializers);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000808
809 // Visit the initializers in source order
810 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Sean Huntcbb67482011-01-08 20:30:50 +0000811 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichet00eb3f92010-12-04 09:14:42 +0000812 if (Init->isAnyMemberInitializer()) {
813 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregora67e03f2010-09-09 21:42:20 +0000814 Init->getMemberLocation(), TU)))
815 return true;
816 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
817 if (Visit(BaseInfo->getTypeLoc()))
818 return true;
819 }
820
821 // Visit the initializer value.
822 if (Expr *Initializer = Init->getInit())
823 if (Visit(MakeCXCursor(Initializer, ND, TU)))
824 return true;
825 }
826 }
827
828 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
829 return true;
830 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000831
Douglas Gregorb1373d02010-01-20 20:59:29 +0000832 return false;
833}
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000834
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000835bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
836 if (VisitDeclaratorDecl(D))
837 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000838
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000839 if (Expr *BitWidth = D->getBitWidth())
840 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000841
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000842 return false;
843}
844
845bool CursorVisitor::VisitVarDecl(VarDecl *D) {
846 if (VisitDeclaratorDecl(D))
847 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000848
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000849 if (Expr *Init = D->getInit())
850 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000851
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000852 return false;
853}
854
Douglas Gregor84b51d72010-09-01 20:16:53 +0000855bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
856 if (VisitDeclaratorDecl(D))
857 return true;
858
859 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
860 if (Expr *DefArg = D->getDefaultArgument())
861 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
862
863 return false;
864}
865
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000866bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
867 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
868 // before visiting these template parameters.
869 if (VisitTemplateParameters(D->getTemplateParameters()))
870 return true;
871
872 return VisitFunctionDecl(D->getTemplatedDecl());
873}
874
Douglas Gregor39d6f072010-08-31 19:02:00 +0000875bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
876 // FIXME: Visit the "outer" template parameter lists on the TagDecl
877 // before visiting these template parameters.
878 if (VisitTemplateParameters(D->getTemplateParameters()))
879 return true;
880
881 return VisitCXXRecordDecl(D->getTemplatedDecl());
882}
883
Douglas Gregor84b51d72010-09-01 20:16:53 +0000884bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
885 if (VisitTemplateParameters(D->getTemplateParameters()))
886 return true;
887
888 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
889 VisitTemplateArgumentLoc(D->getDefaultArgument()))
890 return true;
891
892 return false;
893}
894
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000895bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor4bc1cb62010-03-08 14:59:44 +0000896 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
897 if (Visit(TSInfo->getTypeLoc()))
898 return true;
899
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000900 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000901 PEnd = ND->param_end();
902 P != PEnd; ++P) {
903 if (Visit(MakeCXCursor(*P, TU)))
904 return true;
905 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000906
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000907 if (ND->isThisDeclarationADefinition() &&
908 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
909 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000910
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000911 return false;
912}
913
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000914namespace {
915 struct ContainerDeclsSort {
916 SourceManager &SM;
917 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
918 bool operator()(Decl *A, Decl *B) {
919 SourceLocation L_A = A->getLocStart();
920 SourceLocation L_B = B->getLocStart();
921 assert(L_A.isValid() && L_B.isValid());
922 return SM.isBeforeInTranslationUnit(L_A, L_B);
923 }
924 };
925}
926
Douglas Gregora59e3902010-01-21 23:27:09 +0000927bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000928 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
929 // an @implementation can lexically contain Decls that are not properly
930 // nested in the AST. When we identify such cases, we need to retrofit
931 // this nesting here.
932 if (!DI_current)
933 return VisitDeclContext(D);
934
935 // Scan the Decls that immediately come after the container
936 // in the current DeclContext. If any fall within the
937 // container's lexical region, stash them into a vector
938 // for later processing.
939 llvm::SmallVector<Decl *, 24> DeclsInContainer;
940 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000941 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000942 if (EndLoc.isValid()) {
943 DeclContext::decl_iterator next = *DI_current;
944 while (++next != DE_current) {
945 Decl *D_next = *next;
946 if (!D_next)
947 break;
948 SourceLocation L = D_next->getLocStart();
949 if (!L.isValid())
950 break;
951 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
952 *DI_current = next;
953 DeclsInContainer.push_back(D_next);
954 continue;
955 }
956 break;
957 }
958 }
959
960 // The common case.
961 if (DeclsInContainer.empty())
962 return VisitDeclContext(D);
963
964 // Get all the Decls in the DeclContext, and sort them with the
965 // additional ones we've collected. Then visit them.
966 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
967 I!=E; ++I) {
968 Decl *subDecl = *I;
Ted Kremenek0582c892010-11-02 23:17:51 +0000969 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
970 subDecl->getLocStart().isInvalid())
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000971 continue;
972 DeclsInContainer.push_back(subDecl);
973 }
974
975 // Now sort the Decls so that they appear in lexical order.
976 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
977 ContainerDeclsSort(SM));
978
979 // Now visit the decls.
980 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
981 E = DeclsInContainer.end(); I != E; ++I) {
982 CXCursor Cursor = MakeCXCursor(*I, TU);
983 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
984 if (!V.hasValue())
985 continue;
986 if (!V.getValue())
987 return false;
988 if (Visit(Cursor, true))
989 return true;
990 }
991 return false;
Douglas Gregora59e3902010-01-21 23:27:09 +0000992}
993
Douglas Gregorb1373d02010-01-20 20:59:29 +0000994bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000995 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
996 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000997 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000998
Douglas Gregor78db0cd2010-01-16 15:44:18 +0000999 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1000 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1001 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001002 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001003 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001004
Douglas Gregora59e3902010-01-21 23:27:09 +00001005 return VisitObjCContainerDecl(ND);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001006}
1007
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001008bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1009 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1010 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1011 E = PID->protocol_end(); I != E; ++I, ++PL)
1012 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1013 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001014
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001015 return VisitObjCContainerDecl(PID);
1016}
1017
Ted Kremenek23173d72010-05-18 21:09:07 +00001018bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor83cb9422010-09-09 17:09:21 +00001019 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCallfc929202010-06-04 22:33:30 +00001020 return true;
1021
Ted Kremenek23173d72010-05-18 21:09:07 +00001022 // FIXME: This implements a workaround with @property declarations also being
1023 // installed in the DeclContext for the @interface. Eventually this code
1024 // should be removed.
1025 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1026 if (!CDecl || !CDecl->IsClassExtension())
1027 return false;
1028
1029 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1030 if (!ID)
1031 return false;
1032
1033 IdentifierInfo *PropertyId = PD->getIdentifier();
1034 ObjCPropertyDecl *prevDecl =
1035 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1036
1037 if (!prevDecl)
1038 return false;
1039
1040 // Visit synthesized methods since they will be skipped when visiting
1041 // the @interface.
1042 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001043 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001044 if (Visit(MakeCXCursor(MD, TU)))
1045 return true;
1046
1047 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001048 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001049 if (Visit(MakeCXCursor(MD, TU)))
1050 return true;
1051
1052 return false;
1053}
1054
Douglas Gregorb1373d02010-01-20 20:59:29 +00001055bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001056 // Issue callbacks for super class.
Douglas Gregorb1373d02010-01-20 20:59:29 +00001057 if (D->getSuperClass() &&
1058 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001059 D->getSuperClassLoc(),
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001060 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001061 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001062
Douglas Gregor78db0cd2010-01-16 15:44:18 +00001063 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1064 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1065 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001066 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001067 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001068
Douglas Gregora59e3902010-01-21 23:27:09 +00001069 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001070}
1071
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001072bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1073 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001074}
1075
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001076bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremenekebfa3392010-03-19 20:39:03 +00001077 // 'ID' could be null when dealing with invalid code.
1078 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1079 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1080 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001081
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001082 return VisitObjCImplDecl(D);
1083}
1084
1085bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1086#if 0
1087 // Issue callbacks for super class.
1088 // FIXME: No source location information!
1089 if (D->getSuperClass() &&
1090 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001091 D->getSuperClassLoc(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001092 TU)))
1093 return true;
1094#endif
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001095
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001096 return VisitObjCImplDecl(D);
1097}
1098
1099bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1100 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1101 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1102 E = D->protocol_end();
1103 I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001104 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001105 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001106
1107 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001108}
1109
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001110bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1111 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1112 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1113 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001114
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001115 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001116}
1117
Douglas Gregora4ffd852010-11-17 01:03:52 +00001118bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1119 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1120 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1121
1122 return false;
1123}
1124
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00001125bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1126 return VisitDeclContext(D);
1127}
1128
Douglas Gregor69319002010-08-31 23:48:11 +00001129bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001130 // Visit nested-name-specifier.
Douglas Gregor0cfaf6a2011-02-25 17:08:07 +00001131 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1132 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001133 return true;
Douglas Gregor69319002010-08-31 23:48:11 +00001134
1135 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1136 D->getTargetNameLoc(), TU));
1137}
1138
Douglas Gregor7e242562010-09-01 19:52:22 +00001139bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001140 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001141 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1142 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001143 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001144 }
Douglas Gregor7e242562010-09-01 19:52:22 +00001145
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001146 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1147 return true;
1148
Douglas Gregor7e242562010-09-01 19:52:22 +00001149 return VisitDeclarationNameInfo(D->getNameInfo());
1150}
1151
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001152bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001153 // Visit nested-name-specifier.
Douglas Gregordb992412011-02-25 16:33:46 +00001154 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1155 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001156 return true;
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001157
1158 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1159 D->getIdentLocation(), TU));
1160}
1161
Douglas Gregor7e242562010-09-01 19:52:22 +00001162bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001163 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001164 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1165 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001166 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001167 }
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001168
Douglas Gregor7e242562010-09-01 19:52:22 +00001169 return VisitDeclarationNameInfo(D->getNameInfo());
1170}
1171
1172bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1173 UnresolvedUsingTypenameDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001174 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001175 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1176 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001177 return true;
1178
Douglas Gregor7e242562010-09-01 19:52:22 +00001179 return false;
1180}
1181
Douglas Gregor01829d32010-08-31 14:41:23 +00001182bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1183 switch (Name.getName().getNameKind()) {
1184 case clang::DeclarationName::Identifier:
1185 case clang::DeclarationName::CXXLiteralOperatorName:
1186 case clang::DeclarationName::CXXOperatorName:
1187 case clang::DeclarationName::CXXUsingDirective:
1188 return false;
1189
1190 case clang::DeclarationName::CXXConstructorName:
1191 case clang::DeclarationName::CXXDestructorName:
1192 case clang::DeclarationName::CXXConversionFunctionName:
1193 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1194 return Visit(TSInfo->getTypeLoc());
1195 return false;
1196
1197 case clang::DeclarationName::ObjCZeroArgSelector:
1198 case clang::DeclarationName::ObjCOneArgSelector:
1199 case clang::DeclarationName::ObjCMultiArgSelector:
1200 // FIXME: Per-identifier location info?
1201 return false;
1202 }
1203
1204 return false;
1205}
1206
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001207bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1208 SourceRange Range) {
1209 // FIXME: This whole routine is a hack to work around the lack of proper
1210 // source information in nested-name-specifiers (PR5791). Since we do have
1211 // a beginning source location, we can visit the first component of the
1212 // nested-name-specifier, if it's a single-token component.
1213 if (!NNS)
1214 return false;
1215
1216 // Get the first component in the nested-name-specifier.
1217 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1218 NNS = Prefix;
1219
1220 switch (NNS->getKind()) {
1221 case NestedNameSpecifier::Namespace:
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001222 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1223 TU));
1224
Douglas Gregor14aba762011-02-24 02:36:08 +00001225 case NestedNameSpecifier::NamespaceAlias:
1226 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1227 Range.getBegin(), TU));
1228
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001229 case NestedNameSpecifier::TypeSpec: {
1230 // If the type has a form where we know that the beginning of the source
1231 // range matches up with a reference cursor. Visit the appropriate reference
1232 // cursor.
John McCallf4c73712011-01-19 06:33:43 +00001233 const Type *T = NNS->getAsType();
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001234 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1235 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1236 if (const TagType *Tag = dyn_cast<TagType>(T))
1237 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1238 if (const TemplateSpecializationType *TST
1239 = dyn_cast<TemplateSpecializationType>(T))
1240 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1241 break;
1242 }
1243
1244 case NestedNameSpecifier::TypeSpecWithTemplate:
1245 case NestedNameSpecifier::Global:
1246 case NestedNameSpecifier::Identifier:
1247 break;
1248 }
1249
1250 return false;
1251}
1252
Douglas Gregordc355712011-02-25 00:36:19 +00001253bool
1254CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1255 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1256 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1257 Qualifiers.push_back(Qualifier);
1258
1259 while (!Qualifiers.empty()) {
1260 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1261 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1262 switch (NNS->getKind()) {
1263 case NestedNameSpecifier::Namespace:
1264 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001265 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001266 TU)))
1267 return true;
1268
1269 break;
1270
1271 case NestedNameSpecifier::NamespaceAlias:
1272 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001273 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001274 TU)))
1275 return true;
1276
1277 break;
1278
1279 case NestedNameSpecifier::TypeSpec:
1280 case NestedNameSpecifier::TypeSpecWithTemplate:
1281 if (Visit(Q.getTypeLoc()))
1282 return true;
1283
1284 break;
1285
1286 case NestedNameSpecifier::Global:
1287 case NestedNameSpecifier::Identifier:
1288 break;
1289 }
1290 }
1291
1292 return false;
1293}
1294
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001295bool CursorVisitor::VisitTemplateParameters(
1296 const TemplateParameterList *Params) {
1297 if (!Params)
1298 return false;
1299
1300 for (TemplateParameterList::const_iterator P = Params->begin(),
1301 PEnd = Params->end();
1302 P != PEnd; ++P) {
1303 if (Visit(MakeCXCursor(*P, TU)))
1304 return true;
1305 }
1306
1307 return false;
1308}
1309
Douglas Gregor0b36e612010-08-31 20:37:03 +00001310bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1311 switch (Name.getKind()) {
1312 case TemplateName::Template:
1313 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1314
1315 case TemplateName::OverloadedTemplate:
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001316 // Visit the overloaded template set.
1317 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1318 return true;
1319
Douglas Gregor0b36e612010-08-31 20:37:03 +00001320 return false;
1321
1322 case TemplateName::DependentTemplate:
1323 // FIXME: Visit nested-name-specifier.
1324 return false;
1325
1326 case TemplateName::QualifiedTemplate:
1327 // FIXME: Visit nested-name-specifier.
1328 return Visit(MakeCursorTemplateRef(
1329 Name.getAsQualifiedTemplateName()->getDecl(),
1330 Loc, TU));
Douglas Gregor1aee05d2011-01-15 06:45:20 +00001331
1332 case TemplateName::SubstTemplateTemplateParmPack:
1333 return Visit(MakeCursorTemplateRef(
1334 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1335 Loc, TU));
Douglas Gregor0b36e612010-08-31 20:37:03 +00001336 }
1337
1338 return false;
1339}
1340
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001341bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1342 switch (TAL.getArgument().getKind()) {
1343 case TemplateArgument::Null:
1344 case TemplateArgument::Integral:
Douglas Gregor87dd6972010-12-20 16:52:59 +00001345 case TemplateArgument::Pack:
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001346 return false;
1347
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001348 case TemplateArgument::Type:
1349 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1350 return Visit(TSInfo->getTypeLoc());
1351 return false;
1352
1353 case TemplateArgument::Declaration:
1354 if (Expr *E = TAL.getSourceDeclExpression())
1355 return Visit(MakeCXCursor(E, StmtParent, TU));
1356 return false;
1357
1358 case TemplateArgument::Expression:
1359 if (Expr *E = TAL.getSourceExpression())
1360 return Visit(MakeCXCursor(E, StmtParent, TU));
1361 return false;
1362
1363 case TemplateArgument::Template:
Douglas Gregora7fc9012011-01-05 18:58:31 +00001364 case TemplateArgument::TemplateExpansion:
Douglas Gregorb6744ef2011-03-02 17:09:35 +00001365 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1366 return true;
1367
Douglas Gregora7fc9012011-01-05 18:58:31 +00001368 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregor0b36e612010-08-31 20:37:03 +00001369 TAL.getTemplateNameLoc());
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001370 }
1371
1372 return false;
1373}
1374
Ted Kremeneka0536d82010-05-07 01:04:29 +00001375bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1376 return VisitDeclContext(D);
1377}
1378
Douglas Gregor01829d32010-08-31 14:41:23 +00001379bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1380 return Visit(TL.getUnqualifiedLoc());
1381}
1382
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001383bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00001384 ASTContext &Context = AU->getASTContext();
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001385
1386 // Some builtin types (such as Objective-C's "id", "sel", and
1387 // "Class") have associated declarations. Create cursors for those.
1388 QualType VisitType;
1389 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001390 case BuiltinType::Void:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001391 case BuiltinType::Bool:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001392 case BuiltinType::Char_U:
1393 case BuiltinType::UChar:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001394 case BuiltinType::Char16:
1395 case BuiltinType::Char32:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001396 case BuiltinType::UShort:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001397 case BuiltinType::UInt:
1398 case BuiltinType::ULong:
1399 case BuiltinType::ULongLong:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001400 case BuiltinType::UInt128:
1401 case BuiltinType::Char_S:
1402 case BuiltinType::SChar:
Chris Lattner3f59c972010-12-25 23:25:43 +00001403 case BuiltinType::WChar_U:
1404 case BuiltinType::WChar_S:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001405 case BuiltinType::Short:
1406 case BuiltinType::Int:
1407 case BuiltinType::Long:
1408 case BuiltinType::LongLong:
1409 case BuiltinType::Int128:
1410 case BuiltinType::Float:
1411 case BuiltinType::Double:
1412 case BuiltinType::LongDouble:
1413 case BuiltinType::NullPtr:
1414 case BuiltinType::Overload:
John McCall864c0412011-04-26 20:42:42 +00001415 case BuiltinType::BoundMember:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001416 case BuiltinType::Dependent:
John McCall1de4d4e2011-04-07 08:22:57 +00001417 case BuiltinType::UnknownAny:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001418 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001419
Ted Kremenekc4174cc2010-02-18 18:52:18 +00001420 case BuiltinType::ObjCId:
1421 VisitType = Context.getObjCIdType();
1422 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001423
1424 case BuiltinType::ObjCClass:
1425 VisitType = Context.getObjCClassType();
1426 break;
1427
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001428 case BuiltinType::ObjCSel:
1429 VisitType = Context.getObjCSelType();
1430 break;
1431 }
1432
1433 if (!VisitType.isNull()) {
1434 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001435 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001436 TU));
1437 }
1438
1439 return false;
1440}
1441
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001442bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
Richard Smith162e1c12011-04-15 14:24:37 +00001443 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001444}
1445
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001446bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1447 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1448}
1449
1450bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1451 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1452}
1453
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001454bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001455 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001456 // no context information with which we can match up the depth/index in the
1457 // type to the appropriate
1458 return false;
1459}
1460
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001461bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1462 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1463 return true;
1464
John McCallc12c5bb2010-05-15 11:32:37 +00001465 return false;
1466}
1467
1468bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1469 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1470 return true;
1471
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001472 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1473 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1474 TU)))
1475 return true;
1476 }
1477
1478 return false;
1479}
1480
1481bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCallc12c5bb2010-05-15 11:32:37 +00001482 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001483}
1484
Abramo Bagnara075f8f12010-12-10 16:29:40 +00001485bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1486 return Visit(TL.getInnerLoc());
1487}
1488
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001489bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1490 return Visit(TL.getPointeeLoc());
1491}
1492
1493bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001502 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001503}
1504
1505bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001506 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001507}
1508
Douglas Gregor01829d32010-08-31 14:41:23 +00001509bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1510 bool SkipResultType) {
1511 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001512 return true;
1513
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001514 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek5dbacb42010-04-07 00:27:13 +00001515 if (Decl *D = TL.getArg(I))
1516 if (Visit(MakeCXCursor(D, TU)))
1517 return true;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001518
1519 return false;
1520}
1521
1522bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1523 if (Visit(TL.getElementLoc()))
1524 return true;
1525
1526 if (Expr *Size = TL.getSizeExpr())
1527 return Visit(MakeCXCursor(Size, StmtParent, TU));
1528
1529 return false;
1530}
1531
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001532bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1533 TemplateSpecializationTypeLoc TL) {
Douglas Gregor0b36e612010-08-31 20:37:03 +00001534 // Visit the template name.
1535 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1536 TL.getTemplateNameLoc()))
1537 return true;
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001538
1539 // Visit the template arguments.
1540 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1541 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1542 return true;
1543
1544 return false;
1545}
1546
Douglas Gregor2332c112010-01-21 20:48:56 +00001547bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1548 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1549}
1550
1551bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1552 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1553 return Visit(TSInfo->getTypeLoc());
1554
1555 return false;
1556}
1557
Douglas Gregor2494dd02011-03-01 01:34:45 +00001558bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1559 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1560 return true;
1561
1562 return false;
1563}
1564
Douglas Gregor94fdffa2011-03-01 20:11:18 +00001565bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1566 DependentTemplateSpecializationTypeLoc TL) {
1567 // Visit the nested-name-specifier, if there is one.
1568 if (TL.getQualifierLoc() &&
1569 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1570 return true;
1571
1572 // Visit the template arguments.
1573 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1574 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1575 return true;
1576
1577 return false;
1578}
1579
Douglas Gregor9e876872011-03-01 18:12:44 +00001580bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1581 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1582 return true;
1583
1584 return Visit(TL.getNamedTypeLoc());
1585}
1586
Douglas Gregor7536dd52010-12-20 02:24:11 +00001587bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1588 return Visit(TL.getPatternLoc());
1589}
1590
Ted Kremenek3064ef92010-08-27 21:34:58 +00001591bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001592 // Visit the nested-name-specifier, if present.
1593 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1594 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1595 return true;
1596
Ted Kremenek3064ef92010-08-27 21:34:58 +00001597 if (D->isDefinition()) {
1598 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1599 E = D->bases_end(); I != E; ++I) {
1600 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1601 return true;
1602 }
1603 }
1604
1605 return VisitTagDecl(D);
1606}
1607
Ted Kremenek09dfa372010-02-18 05:46:33 +00001608bool CursorVisitor::VisitAttributes(Decl *D) {
Sean Huntcf807c42010-08-18 23:23:40 +00001609 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1610 i != e; ++i)
1611 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek09dfa372010-02-18 05:46:33 +00001612 return true;
1613
1614 return false;
1615}
1616
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001617//===----------------------------------------------------------------------===//
1618// Data-recursive visitor methods.
1619//===----------------------------------------------------------------------===//
1620
Ted Kremenek28a71942010-11-13 00:36:47 +00001621namespace {
Ted Kremenek035dc412010-11-13 00:36:50 +00001622#define DEF_JOB(NAME, DATA, KIND)\
1623class NAME : public VisitorJob {\
1624public:\
1625 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1626 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenekf64d8032010-11-18 00:02:32 +00001627 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek035dc412010-11-13 00:36:50 +00001628};
1629
1630DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1631DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001632DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001633DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek60608ec2010-11-17 00:50:47 +00001634DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1635 ExplicitTemplateArgsVisitKind)
Douglas Gregor94d96292011-01-19 20:34:17 +00001636DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001637#undef DEF_JOB
1638
1639class DeclVisit : public VisitorJob {
1640public:
1641 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1642 VisitorJob(parent, VisitorJob::DeclVisitKind,
1643 d, isFirst ? (void*) 1 : (void*) 0) {}
1644 static bool classof(const VisitorJob *VJ) {
Ted Kremenek82f3c502010-11-15 22:23:26 +00001645 return VJ->getKind() == DeclVisitKind;
Ted Kremenek035dc412010-11-13 00:36:50 +00001646 }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001647 Decl *get() const { return static_cast<Decl*>(data[0]); }
1648 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek035dc412010-11-13 00:36:50 +00001649};
Ted Kremenek035dc412010-11-13 00:36:50 +00001650class TypeLocVisit : public VisitorJob {
1651public:
1652 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1653 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1654 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1655
1656 static bool classof(const VisitorJob *VJ) {
1657 return VJ->getKind() == TypeLocVisitKind;
1658 }
1659
Ted Kremenek82f3c502010-11-15 22:23:26 +00001660 TypeLoc get() const {
Ted Kremenekf64d8032010-11-18 00:02:32 +00001661 QualType T = QualType::getFromOpaquePtr(data[0]);
1662 return TypeLoc(T, data[1]);
Ted Kremenek035dc412010-11-13 00:36:50 +00001663 }
1664};
1665
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001666class LabelRefVisit : public VisitorJob {
1667public:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001668 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1669 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001670 labelLoc.getPtrEncoding()) {}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001671
1672 static bool classof(const VisitorJob *VJ) {
1673 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1674 }
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001675 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001676 SourceLocation getLoc() const {
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001677 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001678};
1679class NestedNameSpecifierVisit : public VisitorJob {
1680public:
1681 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1682 CXCursor parent)
1683 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001684 NS, R.getBegin().getPtrEncoding(),
1685 R.getEnd().getPtrEncoding()) {}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001686 static bool classof(const VisitorJob *VJ) {
1687 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1688 }
1689 NestedNameSpecifier *get() const {
1690 return static_cast<NestedNameSpecifier*>(data[0]);
1691 }
1692 SourceRange getSourceRange() const {
1693 SourceLocation A =
1694 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1695 SourceLocation B =
1696 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1697 return SourceRange(A, B);
1698 }
1699};
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001700
1701class NestedNameSpecifierLocVisit : public VisitorJob {
1702public:
1703 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1704 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1705 Qualifier.getNestedNameSpecifier(),
1706 Qualifier.getOpaqueData()) { }
1707
1708 static bool classof(const VisitorJob *VJ) {
1709 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1710 }
1711
1712 NestedNameSpecifierLoc get() const {
1713 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1714 data[1]);
1715 }
1716};
1717
Ted Kremenekf64d8032010-11-18 00:02:32 +00001718class DeclarationNameInfoVisit : public VisitorJob {
1719public:
1720 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1721 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1722 static bool classof(const VisitorJob *VJ) {
1723 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1724 }
1725 DeclarationNameInfo get() const {
1726 Stmt *S = static_cast<Stmt*>(data[0]);
1727 switch (S->getStmtClass()) {
1728 default:
1729 llvm_unreachable("Unhandled Stmt");
1730 case Stmt::CXXDependentScopeMemberExprClass:
1731 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1732 case Stmt::DependentScopeDeclRefExprClass:
1733 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1734 }
1735 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001736};
Ted Kremenekcdba6592010-11-18 00:42:18 +00001737class MemberRefVisit : public VisitorJob {
1738public:
1739 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1740 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001741 L.getPtrEncoding()) {}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001742 static bool classof(const VisitorJob *VJ) {
1743 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1744 }
1745 FieldDecl *get() const {
1746 return static_cast<FieldDecl*>(data[0]);
1747 }
1748 SourceLocation getLoc() const {
1749 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1750 }
1751};
Ted Kremenek28a71942010-11-13 00:36:47 +00001752class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1753 VisitorWorkList &WL;
1754 CXCursor Parent;
1755public:
1756 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1757 : WL(wl), Parent(parent) {}
1758
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001759 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001760 void VisitBlockExpr(BlockExpr *B);
Ted Kremenek28a71942010-11-13 00:36:47 +00001761 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenek083c7e22010-11-13 05:38:03 +00001762 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001763 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001764 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001765 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001766 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001767 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001768 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001769 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001770 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek55b933a2010-11-17 00:50:36 +00001771 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001772 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001773 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek035dc412010-11-13 00:36:50 +00001774 void VisitDeclStmt(DeclStmt *S);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001775 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001776 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001777 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1778 void VisitForStmt(ForStmt *FS);
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001779 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenek28a71942010-11-13 00:36:47 +00001780 void VisitIfStmt(IfStmt *If);
1781 void VisitInitListExpr(InitListExpr *IE);
1782 void VisitMemberExpr(MemberExpr *M);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001783 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001784 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001785 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1786 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00001787 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001788 void VisitStmt(Stmt *S);
1789 void VisitSwitchStmt(SwitchStmt *S);
1790 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek2939b6f2010-11-17 00:50:50 +00001791 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet6ad6f282010-12-07 00:08:36 +00001792 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
John Wiegley21ff2e52011-04-28 00:16:57 +00001793 void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
John Wiegley55262202011-04-25 06:54:41 +00001794 void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001795 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenek9d3bf792010-11-17 00:50:43 +00001796 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor94d96292011-01-19 20:34:17 +00001797 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregoree8aff02011-01-04 17:33:58 +00001798
Ted Kremenek28a71942010-11-13 00:36:47 +00001799private:
Ted Kremenekf64d8032010-11-18 00:02:32 +00001800 void AddDeclarationNameInfo(Stmt *S);
1801 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001802 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek60608ec2010-11-17 00:50:47 +00001803 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001804 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenek28a71942010-11-13 00:36:47 +00001805 void AddStmt(Stmt *S);
Ted Kremenek035dc412010-11-13 00:36:50 +00001806 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenek28a71942010-11-13 00:36:47 +00001807 void AddTypeLoc(TypeSourceInfo *TI);
1808 void EnqueueChildren(Stmt *S);
1809};
1810} // end anonyous namespace
1811
Ted Kremenekf64d8032010-11-18 00:02:32 +00001812void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1813 // 'S' should always be non-null, since it comes from the
1814 // statement we are visiting.
1815 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1816}
1817void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1818 SourceRange R) {
1819 if (N)
1820 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1821}
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001822
1823void
1824EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1825 if (Qualifier)
1826 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1827}
1828
Ted Kremenek28a71942010-11-13 00:36:47 +00001829void EnqueueVisitor::AddStmt(Stmt *S) {
1830 if (S)
1831 WL.push_back(StmtVisit(S, Parent));
1832}
Ted Kremenek035dc412010-11-13 00:36:50 +00001833void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001834 if (D)
Ted Kremenek035dc412010-11-13 00:36:50 +00001835 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenek28a71942010-11-13 00:36:47 +00001836}
Ted Kremenek60608ec2010-11-17 00:50:47 +00001837void EnqueueVisitor::
1838 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1839 if (A)
1840 WL.push_back(ExplicitTemplateArgsVisit(
1841 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1842}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001843void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1844 if (D)
1845 WL.push_back(MemberRefVisit(D, L, Parent));
1846}
Ted Kremenek28a71942010-11-13 00:36:47 +00001847void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1848 if (TI)
1849 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1850 }
1851void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremeneka6b70432010-11-12 21:34:09 +00001852 unsigned size = WL.size();
John McCall7502c1d2011-02-13 04:07:26 +00001853 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001854 AddStmt(*Child);
Ted Kremeneka6b70432010-11-12 21:34:09 +00001855 }
1856 if (size == WL.size())
1857 return;
1858 // Now reverse the entries we just added. This will match the DFS
1859 // ordering performed by the worklist.
1860 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1861 std::reverse(I, E);
1862}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001863void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1864 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1865}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001866void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1867 AddDecl(B->getBlockDecl());
1868}
Ted Kremenek28a71942010-11-13 00:36:47 +00001869void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1870 EnqueueChildren(E);
1871 AddTypeLoc(E->getTypeSourceInfo());
1872}
Ted Kremenek083c7e22010-11-13 05:38:03 +00001873void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1874 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1875 E = S->body_rend(); I != E; ++I) {
1876 AddStmt(*I);
1877 }
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001878}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001879void EnqueueVisitor::
1880VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1881 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1882 AddDeclarationNameInfo(E);
Douglas Gregor7c3179c2011-02-28 18:50:33 +00001883 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1884 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001885 if (!E->isImplicitAccess())
1886 AddStmt(E->getBase());
1887}
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001888void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1889 // Enqueue the initializer or constructor arguments.
1890 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1891 AddStmt(E->getConstructorArg(I-1));
1892 // Enqueue the array size, if any.
1893 AddStmt(E->getArraySize());
1894 // Enqueue the allocated type.
1895 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1896 // Enqueue the placement arguments.
1897 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1898 AddStmt(E->getPlacementArg(I-1));
1899}
Ted Kremenek28a71942010-11-13 00:36:47 +00001900void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenek8b8d8c92010-11-13 05:55:56 +00001901 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1902 AddStmt(CE->getArg(I-1));
Ted Kremenek28a71942010-11-13 00:36:47 +00001903 AddStmt(CE->getCallee());
1904 AddStmt(CE->getArg(0));
1905}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001906void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1907 // Visit the name of the type being destroyed.
1908 AddTypeLoc(E->getDestroyedTypeInfo());
1909 // Visit the scope type that looks disturbingly like the nested-name-specifier
1910 // but isn't.
1911 AddTypeLoc(E->getScopeTypeInfo());
1912 // Visit the nested-name-specifier.
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001913 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1914 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001915 // Visit base expression.
1916 AddStmt(E->getBase());
1917}
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001918void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1919 AddTypeLoc(E->getTypeSourceInfo());
1920}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001921void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1922 EnqueueChildren(E);
1923 AddTypeLoc(E->getTypeSourceInfo());
1924}
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001925void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1926 EnqueueChildren(E);
1927 if (E->isTypeOperand())
1928 AddTypeLoc(E->getTypeOperandSourceInfo());
1929}
Ted Kremenek55b933a2010-11-17 00:50:36 +00001930
1931void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1932 *E) {
1933 EnqueueChildren(E);
1934 AddTypeLoc(E->getTypeSourceInfo());
1935}
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001936void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1937 EnqueueChildren(E);
1938 if (E->isTypeOperand())
1939 AddTypeLoc(E->getTypeOperandSourceInfo());
1940}
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001941void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00001942 if (DR->hasExplicitTemplateArgs()) {
1943 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1944 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001945 WL.push_back(DeclRefExprParts(DR, Parent));
1946}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001947void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1948 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1949 AddDeclarationNameInfo(E);
Douglas Gregor00cf3cc2011-02-25 20:49:16 +00001950 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenekf64d8032010-11-18 00:02:32 +00001951}
Ted Kremenek035dc412010-11-13 00:36:50 +00001952void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1953 unsigned size = WL.size();
1954 bool isFirst = true;
1955 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1956 D != DEnd; ++D) {
1957 AddDecl(*D, isFirst);
1958 isFirst = false;
1959 }
1960 if (size == WL.size())
1961 return;
1962 // Now reverse the entries we just added. This will match the DFS
1963 // ordering performed by the worklist.
1964 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1965 std::reverse(I, E);
1966}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001967void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1968 AddStmt(E->getInit());
1969 typedef DesignatedInitExpr::Designator Designator;
1970 for (DesignatedInitExpr::reverse_designators_iterator
1971 D = E->designators_rbegin(), DEnd = E->designators_rend();
1972 D != DEnd; ++D) {
1973 if (D->isFieldDesignator()) {
1974 if (FieldDecl *Field = D->getField())
1975 AddMemberRef(Field, D->getFieldLoc());
1976 continue;
1977 }
1978 if (D->isArrayDesignator()) {
1979 AddStmt(E->getArrayIndex(*D));
1980 continue;
1981 }
1982 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1983 AddStmt(E->getArrayRangeEnd(*D));
1984 AddStmt(E->getArrayRangeStart(*D));
1985 }
1986}
Ted Kremenek28a71942010-11-13 00:36:47 +00001987void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1988 EnqueueChildren(E);
1989 AddTypeLoc(E->getTypeInfoAsWritten());
1990}
1991void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1992 AddStmt(FS->getBody());
1993 AddStmt(FS->getInc());
1994 AddStmt(FS->getCond());
1995 AddDecl(FS->getConditionVariable());
1996 AddStmt(FS->getInit());
1997}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001998void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1999 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2000}
Ted Kremenek28a71942010-11-13 00:36:47 +00002001void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
2002 AddStmt(If->getElse());
2003 AddStmt(If->getThen());
2004 AddStmt(If->getCond());
2005 AddDecl(If->getConditionVariable());
2006}
2007void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
2008 // We care about the syntactic form of the initializer list, only.
2009 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2010 IE = Syntactic;
2011 EnqueueChildren(IE);
2012}
2013void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor89629a72010-11-17 17:15:08 +00002014 WL.push_back(MemberExprParts(M, Parent));
2015
2016 // If the base of the member access expression is an implicit 'this', don't
2017 // visit it.
2018 // FIXME: If we ever want to show these implicit accesses, this will be
2019 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor75e85042011-03-02 21:06:53 +00002020 if (!M->isImplicitAccess())
2021 AddStmt(M->getBase());
Ted Kremenek28a71942010-11-13 00:36:47 +00002022}
Ted Kremenek73d15c42010-11-13 01:09:29 +00002023void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2024 AddTypeLoc(E->getEncodedTypeSourceInfo());
2025}
Ted Kremenek28a71942010-11-13 00:36:47 +00002026void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2027 EnqueueChildren(M);
2028 AddTypeLoc(M->getClassReceiverTypeInfo());
2029}
Ted Kremenekcdba6592010-11-18 00:42:18 +00002030void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2031 // Visit the components of the offsetof expression.
2032 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2033 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2034 const OffsetOfNode &Node = E->getComponent(I-1);
2035 switch (Node.getKind()) {
2036 case OffsetOfNode::Array:
2037 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2038 break;
2039 case OffsetOfNode::Field:
Abramo Bagnara06dec892011-03-12 09:45:03 +00002040 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenekcdba6592010-11-18 00:42:18 +00002041 break;
2042 case OffsetOfNode::Identifier:
2043 case OffsetOfNode::Base:
2044 continue;
2045 }
2046 }
2047 // Visit the type into which we're computing the offset.
2048 AddTypeLoc(E->getTypeSourceInfo());
2049}
Ted Kremenek28a71942010-11-13 00:36:47 +00002050void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00002051 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenek60458782010-11-12 21:34:16 +00002052 WL.push_back(OverloadExprParts(E, Parent));
2053}
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00002054void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2055 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00002056 EnqueueChildren(E);
2057 if (E->isArgumentType())
2058 AddTypeLoc(E->getArgumentTypeInfo());
2059}
Ted Kremenek28a71942010-11-13 00:36:47 +00002060void EnqueueVisitor::VisitStmt(Stmt *S) {
2061 EnqueueChildren(S);
2062}
2063void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2064 AddStmt(S->getBody());
2065 AddStmt(S->getCond());
2066 AddDecl(S->getConditionVariable());
2067}
Ted Kremenekfafa75a2010-11-17 00:50:39 +00002068
Ted Kremenek28a71942010-11-13 00:36:47 +00002069void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2070 AddStmt(W->getBody());
2071 AddStmt(W->getCond());
2072 AddDecl(W->getConditionVariable());
2073}
John Wiegley21ff2e52011-04-28 00:16:57 +00002074
Ted Kremenek2939b6f2010-11-17 00:50:50 +00002075void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2076 AddTypeLoc(E->getQueriedTypeSourceInfo());
2077}
Francois Pichet6ad6f282010-12-07 00:08:36 +00002078
2079void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet6ad6f282010-12-07 00:08:36 +00002080 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichet0a03a3f2010-12-08 09:11:05 +00002081 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet6ad6f282010-12-07 00:08:36 +00002082}
2083
John Wiegley21ff2e52011-04-28 00:16:57 +00002084void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2085 AddTypeLoc(E->getQueriedTypeSourceInfo());
2086}
2087
John Wiegley55262202011-04-25 06:54:41 +00002088void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2089 EnqueueChildren(E);
2090}
2091
Ted Kremenek28a71942010-11-13 00:36:47 +00002092void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2093 VisitOverloadExpr(U);
2094 if (!U->isImplicitAccess())
2095 AddStmt(U->getBase());
2096}
Ted Kremenek9d3bf792010-11-17 00:50:43 +00002097void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2098 AddStmt(E->getSubExpr());
2099 AddTypeLoc(E->getWrittenTypeInfo());
2100}
Douglas Gregor94d96292011-01-19 20:34:17 +00002101void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2102 WL.push_back(SizeOfPackExprParts(E, Parent));
2103}
Ted Kremenek60458782010-11-12 21:34:16 +00002104
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002105void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenek28a71942010-11-13 00:36:47 +00002106 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002107}
2108
2109bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2110 if (RegionOfInterest.isValid()) {
2111 SourceRange Range = getRawCursorExtent(C);
2112 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2113 return false;
2114 }
2115 return true;
2116}
2117
2118bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2119 while (!WL.empty()) {
2120 // Dequeue the worklist item.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002121 VisitorJob LI = WL.back();
2122 WL.pop_back();
2123
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002124 // Set the Parent field, then back to its old value once we're done.
2125 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2126
2127 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00002128 case VisitorJob::DeclVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002129 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenekf1107452010-11-12 18:26:56 +00002130 if (!D)
2131 continue;
2132
2133 // For now, perform default visitation for Decls.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002134 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenekf1107452010-11-12 18:26:56 +00002135 return true;
2136
2137 continue;
2138 }
Ted Kremenek60608ec2010-11-17 00:50:47 +00002139 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2140 const ExplicitTemplateArgumentList *ArgList =
2141 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2142 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2143 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2144 Arg != ArgEnd; ++Arg) {
2145 if (VisitTemplateArgumentLoc(*Arg))
2146 return true;
2147 }
2148 continue;
2149 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002150 case VisitorJob::TypeLocVisitKind: {
2151 // Perform default visitation for TypeLocs.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002152 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002153 return true;
2154 continue;
2155 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002156 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002157 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremeneke7455012011-02-23 04:54:51 +00002158 if (LabelStmt *stmt = LS->getStmt()) {
2159 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2160 TU))) {
2161 return true;
2162 }
2163 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002164 continue;
2165 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002166
Ted Kremenekf64d8032010-11-18 00:02:32 +00002167 case VisitorJob::NestedNameSpecifierVisitKind: {
2168 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2169 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2170 return true;
2171 continue;
2172 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002173
2174 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2175 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2176 if (VisitNestedNameSpecifierLoc(V->get()))
2177 return true;
2178 continue;
2179 }
2180
Ted Kremenekf64d8032010-11-18 00:02:32 +00002181 case VisitorJob::DeclarationNameInfoVisitKind: {
2182 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2183 ->get()))
2184 return true;
2185 continue;
2186 }
Ted Kremenekcdba6592010-11-18 00:42:18 +00002187 case VisitorJob::MemberRefVisitKind: {
2188 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2189 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2190 return true;
2191 continue;
2192 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002193 case VisitorJob::StmtVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002194 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002195 if (!S)
2196 continue;
2197
Ted Kremenekf1107452010-11-12 18:26:56 +00002198 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002199 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenekcdba6592010-11-18 00:42:18 +00002200 if (!IsInRegionOfInterest(Cursor))
2201 continue;
2202 switch (Visitor(Cursor, Parent, ClientData)) {
2203 case CXChildVisit_Break: return true;
2204 case CXChildVisit_Continue: break;
2205 case CXChildVisit_Recurse:
2206 EnqueueWorkList(WL, S);
Ted Kremenek82f3c502010-11-15 22:23:26 +00002207 break;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002208 }
Ted Kremenek82f3c502010-11-15 22:23:26 +00002209 continue;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002210 }
2211 case VisitorJob::MemberExprPartsKind: {
2212 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002213 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002214
2215 // Visit the nested-name-specifier
Douglas Gregor40d96a62011-02-28 21:54:11 +00002216 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2217 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002218 return true;
2219
2220 // Visit the declaration name.
2221 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2222 return true;
2223
2224 // Visit the explicitly-specified template arguments, if any.
2225 if (M->hasExplicitTemplateArgs()) {
2226 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2227 *ArgEnd = Arg + M->getNumTemplateArgs();
2228 Arg != ArgEnd; ++Arg) {
2229 if (VisitTemplateArgumentLoc(*Arg))
2230 return true;
2231 }
2232 }
2233 continue;
2234 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002235 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002236 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002237 // Visit nested-name-specifier, if present.
Douglas Gregor40d96a62011-02-28 21:54:11 +00002238 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2239 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002240 return true;
2241 // Visit declaration name.
2242 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2243 return true;
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002244 continue;
2245 }
Ted Kremenek60458782010-11-12 21:34:16 +00002246 case VisitorJob::OverloadExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002247 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenek60458782010-11-12 21:34:16 +00002248 // Visit the nested-name-specifier.
Douglas Gregor4c9be892011-02-28 20:01:57 +00002249 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2250 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek60458782010-11-12 21:34:16 +00002251 return true;
2252 // Visit the declaration name.
2253 if (VisitDeclarationNameInfo(O->getNameInfo()))
2254 return true;
2255 // Visit the overloaded declaration reference.
2256 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2257 return true;
Ted Kremenek60458782010-11-12 21:34:16 +00002258 continue;
2259 }
Douglas Gregor94d96292011-01-19 20:34:17 +00002260 case VisitorJob::SizeOfPackExprPartsKind: {
2261 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2262 NamedDecl *Pack = E->getPack();
2263 if (isa<TemplateTypeParmDecl>(Pack)) {
2264 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2265 E->getPackLoc(), TU)))
2266 return true;
2267
2268 continue;
2269 }
2270
2271 if (isa<TemplateTemplateParmDecl>(Pack)) {
2272 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2273 E->getPackLoc(), TU)))
2274 return true;
2275
2276 continue;
2277 }
2278
2279 // Non-type template parameter packs and function parameter packs are
2280 // treated like DeclRefExpr cursors.
2281 continue;
2282 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002283 }
2284 }
2285 return false;
2286}
2287
Ted Kremenekcdba6592010-11-18 00:42:18 +00002288bool CursorVisitor::Visit(Stmt *S) {
Ted Kremenekd1ded662010-11-15 23:31:32 +00002289 VisitorWorkList *WL = 0;
2290 if (!WorkListFreeList.empty()) {
2291 WL = WorkListFreeList.back();
2292 WL->clear();
2293 WorkListFreeList.pop_back();
2294 }
2295 else {
2296 WL = new VisitorWorkList();
2297 WorkListCache.push_back(WL);
2298 }
2299 EnqueueWorkList(*WL, S);
2300 bool result = RunVisitorWorkList(*WL);
2301 WorkListFreeList.push_back(WL);
2302 return result;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002303}
2304
2305//===----------------------------------------------------------------------===//
2306// Misc. API hooks.
2307//===----------------------------------------------------------------------===//
2308
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002309static llvm::sys::Mutex EnableMultithreadingMutex;
2310static bool EnabledMultithreading;
2311
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002312extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002313CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2314 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002315 // Disable pretty stack trace functionality, which will otherwise be a very
2316 // poor citizen of the world and set up all sorts of signal handlers.
2317 llvm::DisablePrettyStackTrace = true;
2318
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002319 // We use crash recovery to make some of our APIs more reliable, implicitly
2320 // enable it.
2321 llvm::CrashRecoveryContext::Enable();
2322
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002323 // Enable support for multithreading in LLVM.
2324 {
2325 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2326 if (!EnabledMultithreading) {
2327 llvm::llvm_start_multithreaded();
2328 EnabledMultithreading = true;
2329 }
2330 }
2331
Douglas Gregora030b7c2010-01-22 20:35:53 +00002332 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002333 if (excludeDeclarationsFromPCH)
2334 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002335 if (displayDiagnostics)
2336 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002337 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002338}
2339
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002340void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002341 if (CIdx)
2342 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002343}
2344
Ted Kremenekd2427dd2011-03-18 23:05:39 +00002345void clang_toggleCrashRecovery(unsigned isEnabled) {
2346 if (isEnabled)
2347 llvm::CrashRecoveryContext::Enable();
2348 else
2349 llvm::CrashRecoveryContext::Disable();
2350}
2351
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002352CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002353 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002354 if (!CIdx)
2355 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002356
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002357 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002358 FileSystemOptions FileSystemOpts;
2359 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002360
Douglas Gregor28019772010-04-05 23:52:57 +00002361 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremeneka60ed472010-11-16 08:15:36 +00002362 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002363 CXXIdx->getOnlyLocalDecls(),
2364 0, 0, true);
Ted Kremeneka60ed472010-11-16 08:15:36 +00002365 return MakeCXTranslationUnit(TU);
Steve Naroff600866c2009-08-27 19:51:58 +00002366}
2367
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002368unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002369 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002370 CXTranslationUnit_CacheCompletionResults |
2371 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002372}
2373
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002374CXTranslationUnit
2375clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2376 const char *source_filename,
2377 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002378 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002379 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002380 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor5a430212010-07-21 18:52:53 +00002381 return clang_parseTranslationUnit(CIdx, source_filename,
2382 command_line_args, num_command_line_args,
2383 unsaved_files, num_unsaved_files,
2384 CXTranslationUnit_DetailedPreprocessingRecord);
2385}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002386
2387struct ParseTranslationUnitInfo {
2388 CXIndex CIdx;
2389 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002390 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002391 int num_command_line_args;
2392 struct CXUnsavedFile *unsaved_files;
2393 unsigned num_unsaved_files;
2394 unsigned options;
2395 CXTranslationUnit result;
2396};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002397static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002398 ParseTranslationUnitInfo *PTUI =
2399 static_cast<ParseTranslationUnitInfo*>(UserData);
2400 CXIndex CIdx = PTUI->CIdx;
2401 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002402 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002403 int num_command_line_args = PTUI->num_command_line_args;
2404 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2405 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2406 unsigned options = PTUI->options;
2407 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002408
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002409 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002410 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002411
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002412 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2413
Douglas Gregor44c181a2010-07-23 00:33:23 +00002414 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002415 bool CompleteTranslationUnit
2416 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002417 bool CacheCodeCompetionResults
2418 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002419 bool CXXPrecompilePreamble
2420 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2421 bool CXXChainedPCH
2422 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002423
Douglas Gregor5352ac02010-01-28 00:27:43 +00002424 // Configure the diagnostics.
2425 DiagnosticOptions DiagOpts;
Ted Kremenek25a11e12011-03-22 01:15:24 +00002426 llvm::IntrusiveRefCntPtr<Diagnostic>
2427 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2428 command_line_args));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002429
Ted Kremenek25a11e12011-03-22 01:15:24 +00002430 // Recover resources if we crash before exiting this function.
2431 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2432 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2433 DiagCleanup(Diags.getPtr());
2434
2435 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2436 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2437
2438 // Recover resources if we crash before exiting this function.
2439 llvm::CrashRecoveryContextCleanupRegistrar<
2440 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2441
Douglas Gregor4db64a42010-01-23 00:14:00 +00002442 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002443 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002444 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002445 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002446 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2447 Buffer));
Douglas Gregor4db64a42010-01-23 00:14:00 +00002448 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002449
Ted Kremenek25a11e12011-03-22 01:15:24 +00002450 llvm::OwningPtr<std::vector<const char *> >
2451 Args(new std::vector<const char*>());
2452
2453 // Recover resources if we crash before exiting this method.
2454 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2455 ArgsCleanup(Args.get());
2456
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002457 // Since the Clang C library is primarily used by batch tools dealing with
2458 // (often very broken) source code, where spell-checking can have a
2459 // significant negative impact on performance (particularly when
2460 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002461 // Only do this if we haven't found a spell-checking-related argument.
2462 bool FoundSpellCheckingArgument = false;
2463 for (int I = 0; I != num_command_line_args; ++I) {
2464 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2465 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2466 FoundSpellCheckingArgument = true;
2467 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002468 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002469 }
2470 if (!FoundSpellCheckingArgument)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002471 Args->push_back("-fno-spell-checking");
Douglas Gregorb10daed2010-10-11 16:52:23 +00002472
Ted Kremenek25a11e12011-03-22 01:15:24 +00002473 Args->insert(Args->end(), command_line_args,
2474 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002475
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002476 // The 'source_filename' argument is optional. If the caller does not
2477 // specify it then it is assumed that the source file is specified
2478 // in the actual argument list.
2479 // Put the source file after command_line_args otherwise if '-x' flag is
2480 // present it will be unused.
2481 if (source_filename)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002482 Args->push_back(source_filename);
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002483
Douglas Gregor44c181a2010-07-23 00:33:23 +00002484 // Do we need the detailed preprocessing record?
2485 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek25a11e12011-03-22 01:15:24 +00002486 Args->push_back("-Xclang");
2487 Args->push_back("-detailed-preprocessing-record");
Douglas Gregor44c181a2010-07-23 00:33:23 +00002488 }
2489
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002490 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002491 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek4ee99262011-03-22 20:16:19 +00002492 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2493 /* vector::data() not portable */,
2494 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002495 Diags,
2496 CXXIdx->getClangResourcesPath(),
2497 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002498 /*CaptureDiagnostics=*/true,
Ted Kremenek4ee99262011-03-22 20:16:19 +00002499 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek25a11e12011-03-22 01:15:24 +00002500 RemappedFiles->size(),
Argyrios Kyrtzidis299a4a92011-03-08 23:35:24 +00002501 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002502 PrecompilePreamble,
2503 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002504 CacheCodeCompetionResults,
2505 CXXPrecompilePreamble,
2506 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002507
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002508 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002509 // Make sure to check that 'Unit' is non-NULL.
2510 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2511 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2512 DEnd = Unit->stored_diag_end();
2513 D != DEnd; ++D) {
2514 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2515 CXString Msg = clang_formatDiagnostic(&Diag,
2516 clang_defaultDiagnosticDisplayOptions());
2517 fprintf(stderr, "%s\n", clang_getCString(Msg));
2518 clang_disposeString(Msg);
2519 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002520#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002521 // On Windows, force a flush, since there may be multiple copies of
2522 // stderr and stdout in the file system, all with different buffers
2523 // but writing to the same device.
2524 fflush(stderr);
2525#endif
2526 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002527 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002528
Ted Kremeneka60ed472010-11-16 08:15:36 +00002529 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002530}
2531CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2532 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002533 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002534 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002535 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002536 unsigned num_unsaved_files,
2537 unsigned options) {
2538 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002539 num_command_line_args, unsaved_files,
2540 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002541 llvm::CrashRecoveryContext CRC;
2542
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002543 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002544 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2545 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2546 fprintf(stderr, " 'command_line_args' : [");
2547 for (int i = 0; i != num_command_line_args; ++i) {
2548 if (i)
2549 fprintf(stderr, ", ");
2550 fprintf(stderr, "'%s'", command_line_args[i]);
2551 }
2552 fprintf(stderr, "],\n");
2553 fprintf(stderr, " 'unsaved_files' : [");
2554 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2555 if (i)
2556 fprintf(stderr, ", ");
2557 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2558 unsaved_files[i].Length);
2559 }
2560 fprintf(stderr, "],\n");
2561 fprintf(stderr, " 'options' : %d,\n", options);
2562 fprintf(stderr, "}\n");
2563
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002564 return 0;
2565 }
2566
2567 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002568}
2569
Douglas Gregor19998442010-08-13 15:35:05 +00002570unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2571 return CXSaveTranslationUnit_None;
2572}
2573
2574int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2575 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002576 if (!TU)
2577 return 1;
2578
Ted Kremeneka60ed472010-11-16 08:15:36 +00002579 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002580}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002581
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002582void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002583 if (CTUnit) {
2584 // If the translation unit has been marked as unsafe to free, just discard
2585 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002586 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002587 return;
2588
Ted Kremeneka60ed472010-11-16 08:15:36 +00002589 delete static_cast<ASTUnit *>(CTUnit->TUData);
2590 disposeCXStringPool(CTUnit->StringPool);
2591 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002592 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002593}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002594
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002595unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2596 return CXReparse_None;
2597}
2598
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002599struct ReparseTranslationUnitInfo {
2600 CXTranslationUnit TU;
2601 unsigned num_unsaved_files;
2602 struct CXUnsavedFile *unsaved_files;
2603 unsigned options;
2604 int result;
2605};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002606
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002607static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002608 ReparseTranslationUnitInfo *RTUI =
2609 static_cast<ReparseTranslationUnitInfo*>(UserData);
2610 CXTranslationUnit TU = RTUI->TU;
2611 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2612 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2613 unsigned options = RTUI->options;
2614 (void) options;
2615 RTUI->result = 1;
2616
Douglas Gregorabc563f2010-07-19 21:46:24 +00002617 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002618 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002619
Ted Kremeneka60ed472010-11-16 08:15:36 +00002620 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002621 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002622
Ted Kremenek25a11e12011-03-22 01:15:24 +00002623 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2624 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2625
2626 // Recover resources if we crash before exiting this function.
2627 llvm::CrashRecoveryContextCleanupRegistrar<
2628 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2629
Douglas Gregorabc563f2010-07-19 21:46:24 +00002630 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2631 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2632 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002633 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002634 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2635 Buffer));
Douglas Gregorabc563f2010-07-19 21:46:24 +00002636 }
2637
Ted Kremenek4ee99262011-03-22 20:16:19 +00002638 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2639 RemappedFiles->size()))
Douglas Gregor593b0c12010-09-23 18:47:53 +00002640 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002641}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002642
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002643int clang_reparseTranslationUnit(CXTranslationUnit TU,
2644 unsigned num_unsaved_files,
2645 struct CXUnsavedFile *unsaved_files,
2646 unsigned options) {
2647 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2648 options, 0 };
2649 llvm::CrashRecoveryContext CRC;
2650
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002651 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002652 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002653 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002654 return 1;
2655 }
2656
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002657
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002658 return RTUI.result;
2659}
2660
Douglas Gregordf95a132010-08-09 20:45:32 +00002661
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002662CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002663 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002664 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002665
Ted Kremeneka60ed472010-11-16 08:15:36 +00002666 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002667 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002668}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002669
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002670CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002671 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002672 return Result;
2673}
2674
Ted Kremenekfb480492010-01-13 21:46:36 +00002675} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002676
Ted Kremenekfb480492010-01-13 21:46:36 +00002677//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002678// CXSourceLocation and CXSourceRange Operations.
2679//===----------------------------------------------------------------------===//
2680
Douglas Gregorb9790342010-01-22 21:44:22 +00002681extern "C" {
2682CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002683 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002684 return Result;
2685}
2686
2687unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002688 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2689 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2690 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002691}
2692
2693CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2694 CXFile file,
2695 unsigned line,
2696 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002697 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002698 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002699
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002700 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002701 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002702 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002703 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002704 = CXXUnit->getSourceManager().getLocation(File, line, column);
2705 if (SLoc.isInvalid()) {
2706 if (Logging)
2707 llvm::errs() << "clang_getLocation(\"" << File->getName()
2708 << "\", " << line << ", " << column << ") = invalid\n";
2709 return clang_getNullLocation();
2710 }
2711
2712 if (Logging)
2713 llvm::errs() << "clang_getLocation(\"" << File->getName()
2714 << "\", " << line << ", " << column << ") = "
2715 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002716
2717 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2718}
2719
2720CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2721 CXFile file,
2722 unsigned offset) {
2723 if (!tu || !file)
2724 return clang_getNullLocation();
2725
Ted Kremeneka60ed472010-11-16 08:15:36 +00002726 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002727 SourceLocation Start
2728 = CXXUnit->getSourceManager().getLocation(
2729 static_cast<const FileEntry *>(file),
2730 1, 1);
2731 if (Start.isInvalid()) return clang_getNullLocation();
2732
2733 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2734
2735 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002736
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002737 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002738}
2739
Douglas Gregor5352ac02010-01-28 00:27:43 +00002740CXSourceRange clang_getNullRange() {
2741 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2742 return Result;
2743}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002744
Douglas Gregor5352ac02010-01-28 00:27:43 +00002745CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2746 if (begin.ptr_data[0] != end.ptr_data[0] ||
2747 begin.ptr_data[1] != end.ptr_data[1])
2748 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002749
2750 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002751 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002752 return Result;
2753}
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002754} // end: extern "C"
Douglas Gregorb9790342010-01-22 21:44:22 +00002755
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002756static void createNullLocation(CXFile *file, unsigned *line,
2757 unsigned *column, unsigned *offset) {
2758 if (file)
2759 *file = 0;
2760 if (line)
2761 *line = 0;
2762 if (column)
2763 *column = 0;
2764 if (offset)
2765 *offset = 0;
2766 return;
2767}
2768
2769extern "C" {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002770void clang_getInstantiationLocation(CXSourceLocation location,
2771 CXFile *file,
2772 unsigned *line,
2773 unsigned *column,
2774 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002775 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2776
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002777 if (!location.ptr_data[0] || Loc.isInvalid()) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002778 createNullLocation(file, line, column, offset);
Douglas Gregor46766dc2010-01-26 19:19:08 +00002779 return;
2780 }
2781
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002782 const SourceManager &SM =
2783 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002784 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002785
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002786 // Check that the FileID is invalid on the instantiation location.
2787 // This can manifest in invalid code.
2788 FileID fileID = SM.getFileID(InstLoc);
Douglas Gregore23ac652011-04-20 00:21:03 +00002789 bool Invalid = false;
2790 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
2791 if (!sloc.isFile() || Invalid) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002792 createNullLocation(file, line, column, offset);
2793 return;
2794 }
2795
Douglas Gregor1db19de2010-01-19 21:36:55 +00002796 if (file)
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002797 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002798 if (line)
2799 *line = SM.getInstantiationLineNumber(InstLoc);
2800 if (column)
2801 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002802 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002803 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002804}
2805
Douglas Gregora9b06d42010-11-09 06:24:54 +00002806void clang_getSpellingLocation(CXSourceLocation location,
2807 CXFile *file,
2808 unsigned *line,
2809 unsigned *column,
2810 unsigned *offset) {
2811 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2812
2813 if (!location.ptr_data[0] || Loc.isInvalid()) {
2814 if (file)
2815 *file = 0;
2816 if (line)
2817 *line = 0;
2818 if (column)
2819 *column = 0;
2820 if (offset)
2821 *offset = 0;
2822 return;
2823 }
2824
2825 const SourceManager &SM =
2826 *static_cast<const SourceManager*>(location.ptr_data[0]);
2827 SourceLocation SpellLoc = Loc;
2828 if (SpellLoc.isMacroID()) {
2829 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2830 if (SimpleSpellingLoc.isFileID() &&
2831 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2832 SpellLoc = SimpleSpellingLoc;
2833 else
2834 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2835 }
2836
2837 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2838 FileID FID = LocInfo.first;
2839 unsigned FileOffset = LocInfo.second;
2840
2841 if (file)
2842 *file = (void *)SM.getFileEntryForID(FID);
2843 if (line)
2844 *line = SM.getLineNumber(FID, FileOffset);
2845 if (column)
2846 *column = SM.getColumnNumber(FID, FileOffset);
2847 if (offset)
2848 *offset = FileOffset;
2849}
2850
Douglas Gregor1db19de2010-01-19 21:36:55 +00002851CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002852 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002853 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002854 return Result;
2855}
2856
2857CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002858 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002859 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002860 return Result;
2861}
2862
Douglas Gregorb9790342010-01-22 21:44:22 +00002863} // end: extern "C"
2864
Douglas Gregor1db19de2010-01-19 21:36:55 +00002865//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002866// CXFile Operations.
2867//===----------------------------------------------------------------------===//
2868
2869extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002870CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002871 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002872 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002873
Steve Naroff88145032009-10-27 14:35:18 +00002874 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002875 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002876}
2877
2878time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002879 if (!SFile)
2880 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002881
Steve Naroff88145032009-10-27 14:35:18 +00002882 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2883 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002884}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002885
Douglas Gregorb9790342010-01-22 21:44:22 +00002886CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2887 if (!tu)
2888 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002889
Ted Kremeneka60ed472010-11-16 08:15:36 +00002890 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002891
Douglas Gregorb9790342010-01-22 21:44:22 +00002892 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002893 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002894}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002895
Ted Kremenekfb480492010-01-13 21:46:36 +00002896} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002897
Ted Kremenekfb480492010-01-13 21:46:36 +00002898//===----------------------------------------------------------------------===//
2899// CXCursor Operations.
2900//===----------------------------------------------------------------------===//
2901
Ted Kremenekfb480492010-01-13 21:46:36 +00002902static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002903 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2904 return getDeclFromExpr(CE->getSubExpr());
2905
Ted Kremenekfb480492010-01-13 21:46:36 +00002906 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2907 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002908 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2909 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002910 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2911 return ME->getMemberDecl();
2912 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2913 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002914 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002915 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002916
Ted Kremenekfb480492010-01-13 21:46:36 +00002917 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2918 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002919 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2920 if (!CE->isElidable())
2921 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002922 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2923 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002924
Douglas Gregordb1314e2010-10-01 21:11:22 +00002925 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2926 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002927 if (SubstNonTypeTemplateParmPackExpr *NTTP
2928 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2929 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002930 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2931 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2932 isa<ParmVarDecl>(SizeOfPack->getPack()))
2933 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002934
Ted Kremenekfb480492010-01-13 21:46:36 +00002935 return 0;
2936}
2937
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002938static SourceLocation getLocationFromExpr(Expr *E) {
2939 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2940 return /*FIXME:*/Msg->getLeftLoc();
2941 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2942 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002943 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2944 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002945 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2946 return Member->getMemberLoc();
2947 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2948 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002949 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2950 return SizeOfPack->getPackLoc();
2951
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002952 return E->getLocStart();
2953}
2954
Ted Kremenekfb480492010-01-13 21:46:36 +00002955extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002956
2957unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002958 CXCursorVisitor visitor,
2959 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002960 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00002961 getCursorASTUnit(parent)->getMaxPCHLevel(),
2962 false);
Douglas Gregorb1373d02010-01-20 20:59:29 +00002963 return CursorVis.VisitChildren(parent);
2964}
2965
David Chisnall3387c652010-11-03 14:12:26 +00002966#ifndef __has_feature
2967#define __has_feature(x) 0
2968#endif
2969#if __has_feature(blocks)
2970typedef enum CXChildVisitResult
2971 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2972
2973static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2974 CXClientData client_data) {
2975 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2976 return block(cursor, parent);
2977}
2978#else
2979// If we are compiled with a compiler that doesn't have native blocks support,
2980// define and call the block manually, so the
2981typedef struct _CXChildVisitResult
2982{
2983 void *isa;
2984 int flags;
2985 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002986 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2987 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002988} *CXCursorVisitorBlock;
2989
2990static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2991 CXClientData client_data) {
2992 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2993 return block->invoke(block, cursor, parent);
2994}
2995#endif
2996
2997
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002998unsigned clang_visitChildrenWithBlock(CXCursor parent,
2999 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00003000 return clang_visitChildren(parent, visitWithBlock, block);
3001}
3002
Douglas Gregor78205d42010-01-20 21:45:58 +00003003static CXString getDeclSpelling(Decl *D) {
3004 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003005 if (!ND) {
3006 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3007 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3008 return createCXString(Property->getIdentifier()->getName());
3009
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003010 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00003011 }
3012
Douglas Gregor78205d42010-01-20 21:45:58 +00003013 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003014 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003015
Douglas Gregor78205d42010-01-20 21:45:58 +00003016 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
3017 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3018 // and returns different names. NamedDecl returns the class name and
3019 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003020 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003021
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003022 if (isa<UsingDirectiveDecl>(D))
3023 return createCXString("");
3024
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00003025 llvm::SmallString<1024> S;
3026 llvm::raw_svector_ostream os(S);
3027 ND->printName(os);
3028
3029 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00003030}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003031
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003032CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003033 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003034 return clang_getTranslationUnitSpelling(
3035 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003036
Steve Narofff334b4e2009-09-02 18:26:48 +00003037 if (clang_isReference(C.kind)) {
3038 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00003039 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00003040 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003041 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003042 }
3043 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00003044 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003045 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003046 }
3047 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00003048 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00003049 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003050 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003051 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00003052 case CXCursor_CXXBaseSpecifier: {
3053 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3054 return createCXString(B->getType().getAsString());
3055 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003056 case CXCursor_TypeRef: {
3057 TypeDecl *Type = getCursorTypeRef(C).first;
3058 assert(Type && "Missing type decl");
3059
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003060 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3061 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003062 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003063 case CXCursor_TemplateRef: {
3064 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00003065 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003066
3067 return createCXString(Template->getNameAsString());
3068 }
Douglas Gregor69319002010-08-31 23:48:11 +00003069
3070 case CXCursor_NamespaceRef: {
3071 NamedDecl *NS = getCursorNamespaceRef(C).first;
3072 assert(NS && "Missing namespace decl");
3073
3074 return createCXString(NS->getNameAsString());
3075 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003076
Douglas Gregora67e03f2010-09-09 21:42:20 +00003077 case CXCursor_MemberRef: {
3078 FieldDecl *Field = getCursorMemberRef(C).first;
3079 assert(Field && "Missing member decl");
3080
3081 return createCXString(Field->getNameAsString());
3082 }
3083
Douglas Gregor36897b02010-09-10 00:22:18 +00003084 case CXCursor_LabelRef: {
3085 LabelStmt *Label = getCursorLabelRef(C).first;
3086 assert(Label && "Missing label");
3087
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003088 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003089 }
3090
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003091 case CXCursor_OverloadedDeclRef: {
3092 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3093 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3094 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3095 return createCXString(ND->getNameAsString());
3096 return createCXString("");
3097 }
3098 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3099 return createCXString(E->getName().getAsString());
3100 OverloadedTemplateStorage *Ovl
3101 = Storage.get<OverloadedTemplateStorage*>();
3102 if (Ovl->size() == 0)
3103 return createCXString("");
3104 return createCXString((*Ovl->begin())->getNameAsString());
3105 }
3106
Daniel Dunbaracca7252009-11-30 20:42:49 +00003107 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003108 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003109 }
3110 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003111
3112 if (clang_isExpression(C.kind)) {
3113 Decl *D = getDeclFromExpr(getCursorExpr(C));
3114 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003115 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003116 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003117 }
3118
Douglas Gregor36897b02010-09-10 00:22:18 +00003119 if (clang_isStatement(C.kind)) {
3120 Stmt *S = getCursorStmt(C);
3121 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003122 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003123
3124 return createCXString("");
3125 }
3126
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003127 if (C.kind == CXCursor_MacroInstantiation)
3128 return createCXString(getCursorMacroInstantiation(C)->getName()
3129 ->getNameStart());
3130
Douglas Gregor572feb22010-03-18 18:04:21 +00003131 if (C.kind == CXCursor_MacroDefinition)
3132 return createCXString(getCursorMacroDefinition(C)->getName()
3133 ->getNameStart());
3134
Douglas Gregorecdcb882010-10-20 22:00:55 +00003135 if (C.kind == CXCursor_InclusionDirective)
3136 return createCXString(getCursorInclusionDirective(C)->getFileName());
3137
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003138 if (clang_isDeclaration(C.kind))
3139 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003140
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003141 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003142}
3143
Douglas Gregor358559d2010-10-02 22:49:11 +00003144CXString clang_getCursorDisplayName(CXCursor C) {
3145 if (!clang_isDeclaration(C.kind))
3146 return clang_getCursorSpelling(C);
3147
3148 Decl *D = getCursorDecl(C);
3149 if (!D)
3150 return createCXString("");
3151
3152 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3153 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3154 D = FunTmpl->getTemplatedDecl();
3155
3156 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3157 llvm::SmallString<64> Str;
3158 llvm::raw_svector_ostream OS(Str);
3159 OS << Function->getNameAsString();
3160 if (Function->getPrimaryTemplate())
3161 OS << "<>";
3162 OS << "(";
3163 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3164 if (I)
3165 OS << ", ";
3166 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3167 }
3168
3169 if (Function->isVariadic()) {
3170 if (Function->getNumParams())
3171 OS << ", ";
3172 OS << "...";
3173 }
3174 OS << ")";
3175 return createCXString(OS.str());
3176 }
3177
3178 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3179 llvm::SmallString<64> Str;
3180 llvm::raw_svector_ostream OS(Str);
3181 OS << ClassTemplate->getNameAsString();
3182 OS << "<";
3183 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3184 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3185 if (I)
3186 OS << ", ";
3187
3188 NamedDecl *Param = Params->getParam(I);
3189 if (Param->getIdentifier()) {
3190 OS << Param->getIdentifier()->getName();
3191 continue;
3192 }
3193
3194 // There is no parameter name, which makes this tricky. Try to come up
3195 // with something useful that isn't too long.
3196 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3197 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3198 else if (NonTypeTemplateParmDecl *NTTP
3199 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3200 OS << NTTP->getType().getAsString(Policy);
3201 else
3202 OS << "template<...> class";
3203 }
3204
3205 OS << ">";
3206 return createCXString(OS.str());
3207 }
3208
3209 if (ClassTemplateSpecializationDecl *ClassSpec
3210 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3211 // If the type was explicitly written, use that.
3212 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3213 return createCXString(TSInfo->getType().getAsString(Policy));
3214
3215 llvm::SmallString<64> Str;
3216 llvm::raw_svector_ostream OS(Str);
3217 OS << ClassSpec->getNameAsString();
3218 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003219 ClassSpec->getTemplateArgs().data(),
3220 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003221 Policy);
3222 return createCXString(OS.str());
3223 }
3224
3225 return clang_getCursorSpelling(C);
3226}
3227
Ted Kremeneke68fff62010-02-17 00:41:32 +00003228CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003229 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003230 case CXCursor_FunctionDecl:
3231 return createCXString("FunctionDecl");
3232 case CXCursor_TypedefDecl:
3233 return createCXString("TypedefDecl");
3234 case CXCursor_EnumDecl:
3235 return createCXString("EnumDecl");
3236 case CXCursor_EnumConstantDecl:
3237 return createCXString("EnumConstantDecl");
3238 case CXCursor_StructDecl:
3239 return createCXString("StructDecl");
3240 case CXCursor_UnionDecl:
3241 return createCXString("UnionDecl");
3242 case CXCursor_ClassDecl:
3243 return createCXString("ClassDecl");
3244 case CXCursor_FieldDecl:
3245 return createCXString("FieldDecl");
3246 case CXCursor_VarDecl:
3247 return createCXString("VarDecl");
3248 case CXCursor_ParmDecl:
3249 return createCXString("ParmDecl");
3250 case CXCursor_ObjCInterfaceDecl:
3251 return createCXString("ObjCInterfaceDecl");
3252 case CXCursor_ObjCCategoryDecl:
3253 return createCXString("ObjCCategoryDecl");
3254 case CXCursor_ObjCProtocolDecl:
3255 return createCXString("ObjCProtocolDecl");
3256 case CXCursor_ObjCPropertyDecl:
3257 return createCXString("ObjCPropertyDecl");
3258 case CXCursor_ObjCIvarDecl:
3259 return createCXString("ObjCIvarDecl");
3260 case CXCursor_ObjCInstanceMethodDecl:
3261 return createCXString("ObjCInstanceMethodDecl");
3262 case CXCursor_ObjCClassMethodDecl:
3263 return createCXString("ObjCClassMethodDecl");
3264 case CXCursor_ObjCImplementationDecl:
3265 return createCXString("ObjCImplementationDecl");
3266 case CXCursor_ObjCCategoryImplDecl:
3267 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003268 case CXCursor_CXXMethod:
3269 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003270 case CXCursor_UnexposedDecl:
3271 return createCXString("UnexposedDecl");
3272 case CXCursor_ObjCSuperClassRef:
3273 return createCXString("ObjCSuperClassRef");
3274 case CXCursor_ObjCProtocolRef:
3275 return createCXString("ObjCProtocolRef");
3276 case CXCursor_ObjCClassRef:
3277 return createCXString("ObjCClassRef");
3278 case CXCursor_TypeRef:
3279 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003280 case CXCursor_TemplateRef:
3281 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003282 case CXCursor_NamespaceRef:
3283 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003284 case CXCursor_MemberRef:
3285 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003286 case CXCursor_LabelRef:
3287 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003288 case CXCursor_OverloadedDeclRef:
3289 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003290 case CXCursor_UnexposedExpr:
3291 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003292 case CXCursor_BlockExpr:
3293 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003294 case CXCursor_DeclRefExpr:
3295 return createCXString("DeclRefExpr");
3296 case CXCursor_MemberRefExpr:
3297 return createCXString("MemberRefExpr");
3298 case CXCursor_CallExpr:
3299 return createCXString("CallExpr");
3300 case CXCursor_ObjCMessageExpr:
3301 return createCXString("ObjCMessageExpr");
3302 case CXCursor_UnexposedStmt:
3303 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003304 case CXCursor_LabelStmt:
3305 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003306 case CXCursor_InvalidFile:
3307 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003308 case CXCursor_InvalidCode:
3309 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003310 case CXCursor_NoDeclFound:
3311 return createCXString("NoDeclFound");
3312 case CXCursor_NotImplemented:
3313 return createCXString("NotImplemented");
3314 case CXCursor_TranslationUnit:
3315 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003316 case CXCursor_UnexposedAttr:
3317 return createCXString("UnexposedAttr");
3318 case CXCursor_IBActionAttr:
3319 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003320 case CXCursor_IBOutletAttr:
3321 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003322 case CXCursor_IBOutletCollectionAttr:
3323 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003324 case CXCursor_PreprocessingDirective:
3325 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003326 case CXCursor_MacroDefinition:
3327 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003328 case CXCursor_MacroInstantiation:
3329 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003330 case CXCursor_InclusionDirective:
3331 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003332 case CXCursor_Namespace:
3333 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003334 case CXCursor_LinkageSpec:
3335 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003336 case CXCursor_CXXBaseSpecifier:
3337 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003338 case CXCursor_Constructor:
3339 return createCXString("CXXConstructor");
3340 case CXCursor_Destructor:
3341 return createCXString("CXXDestructor");
3342 case CXCursor_ConversionFunction:
3343 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003344 case CXCursor_TemplateTypeParameter:
3345 return createCXString("TemplateTypeParameter");
3346 case CXCursor_NonTypeTemplateParameter:
3347 return createCXString("NonTypeTemplateParameter");
3348 case CXCursor_TemplateTemplateParameter:
3349 return createCXString("TemplateTemplateParameter");
3350 case CXCursor_FunctionTemplate:
3351 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003352 case CXCursor_ClassTemplate:
3353 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003354 case CXCursor_ClassTemplatePartialSpecialization:
3355 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003356 case CXCursor_NamespaceAlias:
3357 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003358 case CXCursor_UsingDirective:
3359 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003360 case CXCursor_UsingDeclaration:
3361 return createCXString("UsingDeclaration");
Richard Smith162e1c12011-04-15 14:24:37 +00003362 case CXCursor_TypeAliasDecl:
3363 return createCXString("TypeAliasDecl");
Steve Naroff89922f82009-08-31 00:59:03 +00003364 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003365
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003366 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003367 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003368}
Steve Naroff89922f82009-08-31 00:59:03 +00003369
Ted Kremeneke68fff62010-02-17 00:41:32 +00003370enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3371 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003372 CXClientData client_data) {
3373 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003374
3375 // If our current best cursor is the construction of a temporary object,
3376 // don't replace that cursor with a type reference, because we want
3377 // clang_getCursor() to point at the constructor.
3378 if (clang_isExpression(BestCursor->kind) &&
3379 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3380 cursor.kind == CXCursor_TypeRef)
3381 return CXChildVisit_Recurse;
3382
Douglas Gregor85fe1562010-12-10 07:23:11 +00003383 // Don't override a preprocessing cursor with another preprocessing
3384 // cursor; we want the outermost preprocessing cursor.
3385 if (clang_isPreprocessing(cursor.kind) &&
3386 clang_isPreprocessing(BestCursor->kind))
3387 return CXChildVisit_Recurse;
3388
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003389 *BestCursor = cursor;
3390 return CXChildVisit_Recurse;
3391}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003392
Douglas Gregorb9790342010-01-22 21:44:22 +00003393CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3394 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003395 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003396
Ted Kremeneka60ed472010-11-16 08:15:36 +00003397 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003398 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3399
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003400 // Translate the given source location to make it point at the beginning of
3401 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003402 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003403
3404 // Guard against an invalid SourceLocation, or we may assert in one
3405 // of the following calls.
3406 if (SLoc.isInvalid())
3407 return clang_getNullCursor();
3408
Douglas Gregor40749ee2010-11-03 00:35:38 +00003409 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003410 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3411 CXXUnit->getASTContext().getLangOptions());
3412
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003413 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3414 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003415 // FIXME: Would be great to have a "hint" cursor, then walk from that
3416 // hint cursor upward until we find a cursor whose source range encloses
3417 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003418 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3419 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00003420 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003421 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003422 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003423
3424 if (Logging) {
3425 CXFile SearchFile;
3426 unsigned SearchLine, SearchColumn;
3427 CXFile ResultFile;
3428 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003429 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3430 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003431 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3432
3433 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3434 0);
3435 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3436 &ResultColumn, 0);
3437 SearchFileName = clang_getFileName(SearchFile);
3438 ResultFileName = clang_getFileName(ResultFile);
3439 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003440 USR = clang_getCursorUSR(Result);
3441 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003442 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3443 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003444 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3445 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003446 clang_disposeString(SearchFileName);
3447 clang_disposeString(ResultFileName);
3448 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003449 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003450
3451 CXCursor Definition = clang_getCursorDefinition(Result);
3452 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3453 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3454 CXString DefinitionKindSpelling
3455 = clang_getCursorKindSpelling(Definition.kind);
3456 CXFile DefinitionFile;
3457 unsigned DefinitionLine, DefinitionColumn;
3458 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3459 &DefinitionLine, &DefinitionColumn, 0);
3460 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3461 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3462 clang_getCString(DefinitionKindSpelling),
3463 clang_getCString(DefinitionFileName),
3464 DefinitionLine, DefinitionColumn);
3465 clang_disposeString(DefinitionFileName);
3466 clang_disposeString(DefinitionKindSpelling);
3467 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003468 }
3469
Ted Kremeneke68fff62010-02-17 00:41:32 +00003470 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003471}
3472
Ted Kremenek73885552009-11-17 19:28:59 +00003473CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003474 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003475}
3476
3477unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003478 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003479}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003480
Douglas Gregor9ce55842010-11-20 00:09:34 +00003481unsigned clang_hashCursor(CXCursor C) {
3482 unsigned Index = 0;
3483 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3484 Index = 1;
3485
3486 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3487 std::make_pair(C.kind, C.data[Index]));
3488}
3489
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003490unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003491 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3492}
3493
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003494unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003495 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3496}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003497
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003498unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003499 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3500}
3501
Douglas Gregor97b98722010-01-19 23:20:36 +00003502unsigned clang_isExpression(enum CXCursorKind K) {
3503 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3504}
3505
3506unsigned clang_isStatement(enum CXCursorKind K) {
3507 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3508}
3509
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003510unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3511 return K == CXCursor_TranslationUnit;
3512}
3513
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003514unsigned clang_isPreprocessing(enum CXCursorKind K) {
3515 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3516}
3517
Ted Kremenekad6eff62010-03-08 21:17:29 +00003518unsigned clang_isUnexposed(enum CXCursorKind K) {
3519 switch (K) {
3520 case CXCursor_UnexposedDecl:
3521 case CXCursor_UnexposedExpr:
3522 case CXCursor_UnexposedStmt:
3523 case CXCursor_UnexposedAttr:
3524 return true;
3525 default:
3526 return false;
3527 }
3528}
3529
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003530CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003531 return C.kind;
3532}
3533
Douglas Gregor98258af2010-01-18 22:46:11 +00003534CXSourceLocation clang_getCursorLocation(CXCursor C) {
3535 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003536 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003537 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003538 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3539 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003540 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003541 }
3542
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003543 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003544 std::pair<ObjCProtocolDecl *, SourceLocation> P
3545 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003546 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003547 }
3548
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003549 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003550 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3551 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003552 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003553 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003554
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003555 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003556 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003557 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003558 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003559
3560 case CXCursor_TemplateRef: {
3561 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3562 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3563 }
3564
Douglas Gregor69319002010-08-31 23:48:11 +00003565 case CXCursor_NamespaceRef: {
3566 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3567 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3568 }
3569
Douglas Gregora67e03f2010-09-09 21:42:20 +00003570 case CXCursor_MemberRef: {
3571 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3572 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3573 }
3574
Ted Kremenek3064ef92010-08-27 21:34:58 +00003575 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003576 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3577 if (!BaseSpec)
3578 return clang_getNullLocation();
3579
3580 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3581 return cxloc::translateSourceLocation(getCursorContext(C),
3582 TSInfo->getTypeLoc().getBeginLoc());
3583
3584 return cxloc::translateSourceLocation(getCursorContext(C),
3585 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003586 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003587
Douglas Gregor36897b02010-09-10 00:22:18 +00003588 case CXCursor_LabelRef: {
3589 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3590 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3591 }
3592
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003593 case CXCursor_OverloadedDeclRef:
3594 return cxloc::translateSourceLocation(getCursorContext(C),
3595 getCursorOverloadedDeclRef(C).second);
3596
Douglas Gregorf46034a2010-01-18 23:41:10 +00003597 default:
3598 // FIXME: Need a way to enumerate all non-reference cases.
3599 llvm_unreachable("Missed a reference kind");
3600 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003601 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003602
3603 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003604 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003605 getLocationFromExpr(getCursorExpr(C)));
3606
Douglas Gregor36897b02010-09-10 00:22:18 +00003607 if (clang_isStatement(C.kind))
3608 return cxloc::translateSourceLocation(getCursorContext(C),
3609 getCursorStmt(C)->getLocStart());
3610
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003611 if (C.kind == CXCursor_PreprocessingDirective) {
3612 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3613 return cxloc::translateSourceLocation(getCursorContext(C), L);
3614 }
Douglas Gregor48072312010-03-18 15:23:44 +00003615
3616 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003617 SourceLocation L
3618 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003619 return cxloc::translateSourceLocation(getCursorContext(C), L);
3620 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003621
3622 if (C.kind == CXCursor_MacroDefinition) {
3623 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3624 return cxloc::translateSourceLocation(getCursorContext(C), L);
3625 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003626
3627 if (C.kind == CXCursor_InclusionDirective) {
3628 SourceLocation L
3629 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3630 return cxloc::translateSourceLocation(getCursorContext(C), L);
3631 }
3632
Ted Kremenek9a700d22010-05-12 06:16:13 +00003633 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003634 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003635
Douglas Gregorf46034a2010-01-18 23:41:10 +00003636 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003637 SourceLocation Loc = D->getLocation();
3638 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3639 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003640 // FIXME: Multiple variables declared in a single declaration
3641 // currently lack the information needed to correctly determine their
3642 // ranges when accounting for the type-specifier. We use context
3643 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3644 // and if so, whether it is the first decl.
3645 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3646 if (!cxcursor::isFirstInDeclGroup(C))
3647 Loc = VD->getLocation();
3648 }
3649
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003650 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003651}
Douglas Gregora7bde202010-01-19 00:34:46 +00003652
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003653} // end extern "C"
3654
3655static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003656 if (clang_isReference(C.kind)) {
3657 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003658 case CXCursor_ObjCSuperClassRef:
3659 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003660
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003661 case CXCursor_ObjCProtocolRef:
3662 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003663
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003664 case CXCursor_ObjCClassRef:
3665 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003666
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003667 case CXCursor_TypeRef:
3668 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003669
3670 case CXCursor_TemplateRef:
3671 return getCursorTemplateRef(C).second;
3672
Douglas Gregor69319002010-08-31 23:48:11 +00003673 case CXCursor_NamespaceRef:
3674 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003675
3676 case CXCursor_MemberRef:
3677 return getCursorMemberRef(C).second;
3678
Ted Kremenek3064ef92010-08-27 21:34:58 +00003679 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003680 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003681
Douglas Gregor36897b02010-09-10 00:22:18 +00003682 case CXCursor_LabelRef:
3683 return getCursorLabelRef(C).second;
3684
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003685 case CXCursor_OverloadedDeclRef:
3686 return getCursorOverloadedDeclRef(C).second;
3687
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003688 default:
3689 // FIXME: Need a way to enumerate all non-reference cases.
3690 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003691 }
3692 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003693
3694 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003695 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003696
3697 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003698 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003699
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003700 if (C.kind == CXCursor_PreprocessingDirective)
3701 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003702
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003703 if (C.kind == CXCursor_MacroInstantiation)
3704 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003705
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003706 if (C.kind == CXCursor_MacroDefinition)
3707 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003708
3709 if (C.kind == CXCursor_InclusionDirective)
3710 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3711
Ted Kremenek007a7c92010-11-01 23:26:51 +00003712 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3713 Decl *D = cxcursor::getCursorDecl(C);
3714 SourceRange R = D->getSourceRange();
3715 // FIXME: Multiple variables declared in a single declaration
3716 // currently lack the information needed to correctly determine their
3717 // ranges when accounting for the type-specifier. We use context
3718 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3719 // and if so, whether it is the first decl.
3720 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3721 if (!cxcursor::isFirstInDeclGroup(C))
3722 R.setBegin(VD->getLocation());
3723 }
3724 return R;
3725 }
Douglas Gregor66537982010-11-17 17:14:07 +00003726 return SourceRange();
3727}
3728
3729/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3730/// the decl-specifier-seq for declarations.
3731static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3732 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3733 Decl *D = cxcursor::getCursorDecl(C);
3734 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003735
Douglas Gregor2494dd02011-03-01 01:34:45 +00003736 // Adjust the start of the location for declarations preceded by
3737 // declaration specifiers.
3738 SourceLocation StartLoc;
3739 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3740 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3741 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3742 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3743 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3744 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3745 }
3746
3747 if (StartLoc.isValid() && R.getBegin().isValid() &&
3748 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3749 R.setBegin(StartLoc);
3750
3751 // FIXME: Multiple variables declared in a single declaration
3752 // currently lack the information needed to correctly determine their
3753 // ranges when accounting for the type-specifier. We use context
3754 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3755 // and if so, whether it is the first decl.
3756 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3757 if (!cxcursor::isFirstInDeclGroup(C))
3758 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003759 }
3760
3761 return R;
3762 }
3763
3764 return getRawCursorExtent(C);
3765}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003766
3767extern "C" {
3768
3769CXSourceRange clang_getCursorExtent(CXCursor C) {
3770 SourceRange R = getRawCursorExtent(C);
3771 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003772 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003773
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003774 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003775}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003776
3777CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003778 if (clang_isInvalid(C.kind))
3779 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003780
Ted Kremeneka60ed472010-11-16 08:15:36 +00003781 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003782 if (clang_isDeclaration(C.kind)) {
3783 Decl *D = getCursorDecl(C);
3784 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003785 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003786 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003787 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003788 if (ObjCForwardProtocolDecl *Protocols
3789 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003790 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003791 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3792 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3793 return MakeCXCursor(Property, tu);
3794
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003795 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003796 }
3797
Douglas Gregor97b98722010-01-19 23:20:36 +00003798 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003799 Expr *E = getCursorExpr(C);
3800 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003801 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003802 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003803
3804 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003805 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003806
Douglas Gregor97b98722010-01-19 23:20:36 +00003807 return clang_getNullCursor();
3808 }
3809
Douglas Gregor36897b02010-09-10 00:22:18 +00003810 if (clang_isStatement(C.kind)) {
3811 Stmt *S = getCursorStmt(C);
3812 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek37c2e962011-03-15 23:47:49 +00003813 if (LabelDecl *label = Goto->getLabel())
3814 if (LabelStmt *labelS = label->getStmt())
3815 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003816
3817 return clang_getNullCursor();
3818 }
3819
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003820 if (C.kind == CXCursor_MacroInstantiation) {
3821 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003822 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003823 }
3824
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003825 if (!clang_isReference(C.kind))
3826 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003827
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003828 switch (C.kind) {
3829 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003830 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003831
3832 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003833 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003834
3835 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003836 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003837
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003838 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003839 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003840
3841 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003842 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003843
Douglas Gregor69319002010-08-31 23:48:11 +00003844 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003845 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003846
Douglas Gregora67e03f2010-09-09 21:42:20 +00003847 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003848 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003849
Ted Kremenek3064ef92010-08-27 21:34:58 +00003850 case CXCursor_CXXBaseSpecifier: {
3851 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3852 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003853 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003854 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003855
Douglas Gregor36897b02010-09-10 00:22:18 +00003856 case CXCursor_LabelRef:
3857 // FIXME: We end up faking the "parent" declaration here because we
3858 // don't want to make CXCursor larger.
3859 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003860 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3861 .getTranslationUnitDecl(),
3862 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003863
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003864 case CXCursor_OverloadedDeclRef:
3865 return C;
3866
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003867 default:
3868 // We would prefer to enumerate all non-reference cursor kinds here.
3869 llvm_unreachable("Unhandled reference cursor kind");
3870 break;
3871 }
3872 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003873
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003874 return clang_getNullCursor();
3875}
3876
Douglas Gregorb6998662010-01-19 19:34:47 +00003877CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003878 if (clang_isInvalid(C.kind))
3879 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003880
Ted Kremeneka60ed472010-11-16 08:15:36 +00003881 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003882
Douglas Gregorb6998662010-01-19 19:34:47 +00003883 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003884 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003885 C = clang_getCursorReferenced(C);
3886 WasReference = true;
3887 }
3888
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003889 if (C.kind == CXCursor_MacroInstantiation)
3890 return clang_getCursorReferenced(C);
3891
Douglas Gregorb6998662010-01-19 19:34:47 +00003892 if (!clang_isDeclaration(C.kind))
3893 return clang_getNullCursor();
3894
3895 Decl *D = getCursorDecl(C);
3896 if (!D)
3897 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003898
Douglas Gregorb6998662010-01-19 19:34:47 +00003899 switch (D->getKind()) {
3900 // Declaration kinds that don't really separate the notions of
3901 // declaration and definition.
3902 case Decl::Namespace:
3903 case Decl::Typedef:
Richard Smith162e1c12011-04-15 14:24:37 +00003904 case Decl::TypeAlias:
Douglas Gregorb6998662010-01-19 19:34:47 +00003905 case Decl::TemplateTypeParm:
3906 case Decl::EnumConstant:
3907 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003908 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003909 case Decl::ObjCIvar:
3910 case Decl::ObjCAtDefsField:
3911 case Decl::ImplicitParam:
3912 case Decl::ParmVar:
3913 case Decl::NonTypeTemplateParm:
3914 case Decl::TemplateTemplateParm:
3915 case Decl::ObjCCategoryImpl:
3916 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003917 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003918 case Decl::LinkageSpec:
3919 case Decl::ObjCPropertyImpl:
3920 case Decl::FileScopeAsm:
3921 case Decl::StaticAssert:
3922 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003923 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003924 return C;
3925
3926 // Declaration kinds that don't make any sense here, but are
3927 // nonetheless harmless.
3928 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003929 break;
3930
3931 // Declaration kinds for which the definition is not resolvable.
3932 case Decl::UnresolvedUsingTypename:
3933 case Decl::UnresolvedUsingValue:
3934 break;
3935
3936 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003937 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003938 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003939
3940 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003941 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003942
3943 case Decl::Enum:
3944 case Decl::Record:
3945 case Decl::CXXRecord:
3946 case Decl::ClassTemplateSpecialization:
3947 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003948 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003949 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003950 return clang_getNullCursor();
3951
3952 case Decl::Function:
3953 case Decl::CXXMethod:
3954 case Decl::CXXConstructor:
3955 case Decl::CXXDestructor:
3956 case Decl::CXXConversion: {
3957 const FunctionDecl *Def = 0;
3958 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003959 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003960 return clang_getNullCursor();
3961 }
3962
3963 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003964 // Ask the variable if it has a definition.
3965 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003966 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003967 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003968 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003969
Douglas Gregorb6998662010-01-19 19:34:47 +00003970 case Decl::FunctionTemplate: {
3971 const FunctionDecl *Def = 0;
3972 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003973 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003974 return clang_getNullCursor();
3975 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003976
Douglas Gregorb6998662010-01-19 19:34:47 +00003977 case Decl::ClassTemplate: {
3978 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003979 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003980 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003981 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003982 return clang_getNullCursor();
3983 }
3984
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003985 case Decl::Using:
3986 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003987 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003988
3989 case Decl::UsingShadow:
3990 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003991 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003992 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003993
3994 case Decl::ObjCMethod: {
3995 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3996 if (Method->isThisDeclarationADefinition())
3997 return C;
3998
3999 // Dig out the method definition in the associated
4000 // @implementation, if we have it.
4001 // FIXME: The ASTs should make finding the definition easier.
4002 if (ObjCInterfaceDecl *Class
4003 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4004 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4005 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4006 Method->isInstanceMethod()))
4007 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004008 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004009
4010 return clang_getNullCursor();
4011 }
4012
4013 case Decl::ObjCCategory:
4014 if (ObjCCategoryImplDecl *Impl
4015 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004016 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004017 return clang_getNullCursor();
4018
4019 case Decl::ObjCProtocol:
4020 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
4021 return C;
4022 return clang_getNullCursor();
4023
4024 case Decl::ObjCInterface:
4025 // There are two notions of a "definition" for an Objective-C
4026 // class: the interface and its implementation. When we resolved a
4027 // reference to an Objective-C class, produce the @interface as
4028 // the definition; when we were provided with the interface,
4029 // produce the @implementation as the definition.
4030 if (WasReference) {
4031 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4032 return C;
4033 } else if (ObjCImplementationDecl *Impl
4034 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004035 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004036 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004037
Douglas Gregorb6998662010-01-19 19:34:47 +00004038 case Decl::ObjCProperty:
4039 // FIXME: We don't really know where to find the
4040 // ObjCPropertyImplDecls that implement this property.
4041 return clang_getNullCursor();
4042
4043 case Decl::ObjCCompatibleAlias:
4044 if (ObjCInterfaceDecl *Class
4045 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4046 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004047 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004048
Douglas Gregorb6998662010-01-19 19:34:47 +00004049 return clang_getNullCursor();
4050
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004051 case Decl::ObjCForwardProtocol:
4052 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004053 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004054
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004055 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004056 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004057 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004058
4059 case Decl::Friend:
4060 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004061 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004062 return clang_getNullCursor();
4063
4064 case Decl::FriendTemplate:
4065 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004066 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004067 return clang_getNullCursor();
4068 }
4069
4070 return clang_getNullCursor();
4071}
4072
4073unsigned clang_isCursorDefinition(CXCursor C) {
4074 if (!clang_isDeclaration(C.kind))
4075 return 0;
4076
4077 return clang_getCursorDefinition(C) == C;
4078}
4079
Douglas Gregor1a9d0502010-11-19 23:44:15 +00004080CXCursor clang_getCanonicalCursor(CXCursor C) {
4081 if (!clang_isDeclaration(C.kind))
4082 return C;
4083
4084 if (Decl *D = getCursorDecl(C))
4085 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4086
4087 return C;
4088}
4089
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004090unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004091 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004092 return 0;
4093
4094 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4095 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4096 return E->getNumDecls();
4097
4098 if (OverloadedTemplateStorage *S
4099 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4100 return S->size();
4101
4102 Decl *D = Storage.get<Decl*>();
4103 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00004104 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004105 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4106 return Classes->size();
4107 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4108 return Protocols->protocol_size();
4109
4110 return 0;
4111}
4112
4113CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004114 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004115 return clang_getNullCursor();
4116
4117 if (index >= clang_getNumOverloadedDecls(cursor))
4118 return clang_getNullCursor();
4119
Ted Kremeneka60ed472010-11-16 08:15:36 +00004120 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004121 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4122 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004123 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004124
4125 if (OverloadedTemplateStorage *S
4126 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004127 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004128
4129 Decl *D = Storage.get<Decl*>();
4130 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4131 // FIXME: This is, unfortunately, linear time.
4132 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4133 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004134 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004135 }
4136
4137 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004138 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004139
4140 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004141 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004142
4143 return clang_getNullCursor();
4144}
4145
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004146void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004147 const char **startBuf,
4148 const char **endBuf,
4149 unsigned *startLine,
4150 unsigned *startColumn,
4151 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004152 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004153 assert(getCursorDecl(C) && "CXCursor has null decl");
4154 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004155 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4156 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004157
Steve Naroff4ade6d62009-09-23 17:52:52 +00004158 SourceManager &SM = FD->getASTContext().getSourceManager();
4159 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4160 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4161 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4162 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4163 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4164 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4165}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004166
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004167void clang_enableStackTraces(void) {
4168 llvm::sys::PrintStackTraceOnErrorSignal();
4169}
4170
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004171void clang_executeOnThread(void (*fn)(void*), void *user_data,
4172 unsigned stack_size) {
4173 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4174}
4175
Ted Kremenekfb480492010-01-13 21:46:36 +00004176} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004177
Ted Kremenekfb480492010-01-13 21:46:36 +00004178//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004179// Token-based Operations.
4180//===----------------------------------------------------------------------===//
4181
4182/* CXToken layout:
4183 * int_data[0]: a CXTokenKind
4184 * int_data[1]: starting token location
4185 * int_data[2]: token length
4186 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004187 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004188 * otherwise unused.
4189 */
4190extern "C" {
4191
4192CXTokenKind clang_getTokenKind(CXToken CXTok) {
4193 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4194}
4195
4196CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4197 switch (clang_getTokenKind(CXTok)) {
4198 case CXToken_Identifier:
4199 case CXToken_Keyword:
4200 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004201 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4202 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004203
4204 case CXToken_Literal: {
4205 // We have stashed the starting pointer in the ptr_data field. Use it.
4206 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004207 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004208 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004209
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004210 case CXToken_Punctuation:
4211 case CXToken_Comment:
4212 break;
4213 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004214
4215 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004216 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004217 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004218 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004219 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004220
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004221 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4222 std::pair<FileID, unsigned> LocInfo
4223 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004224 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004225 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004226 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4227 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004228 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004229
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004230 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004231}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004232
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004233CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004234 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004235 if (!CXXUnit)
4236 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004237
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004238 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4239 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4240}
4241
4242CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004243 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004244 if (!CXXUnit)
4245 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004246
4247 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004248 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4249}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004250
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004251void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4252 CXToken **Tokens, unsigned *NumTokens) {
4253 if (Tokens)
4254 *Tokens = 0;
4255 if (NumTokens)
4256 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004257
Ted Kremeneka60ed472010-11-16 08:15:36 +00004258 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004259 if (!CXXUnit || !Tokens || !NumTokens)
4260 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004261
Douglas Gregorbdf60622010-03-05 21:16:25 +00004262 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4263
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004264 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004265 if (R.isInvalid())
4266 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004267
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004268 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4269 std::pair<FileID, unsigned> BeginLocInfo
4270 = SourceMgr.getDecomposedLoc(R.getBegin());
4271 std::pair<FileID, unsigned> EndLocInfo
4272 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004273
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004274 // Cannot tokenize across files.
4275 if (BeginLocInfo.first != EndLocInfo.first)
4276 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004277
4278 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004279 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004280 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004281 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004282 if (Invalid)
4283 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004284
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004285 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4286 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004287 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004288 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004289
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004290 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004291 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004292 llvm::SmallVector<CXToken, 32> CXTokens;
4293 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004294 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004295 do {
4296 // Lex the next token
4297 Lex.LexFromRawLexer(Tok);
4298 if (Tok.is(tok::eof))
4299 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004300
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004301 // Initialize the CXToken.
4302 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004303
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004304 // - Common fields
4305 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4306 CXTok.int_data[2] = Tok.getLength();
4307 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004308
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004309 // - Kind-specific fields
4310 if (Tok.isLiteral()) {
4311 CXTok.int_data[0] = CXToken_Literal;
4312 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004313 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004314 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004315 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004316 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004317
David Chisnall096428b2010-10-13 21:44:48 +00004318 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004319 CXTok.int_data[0] = CXToken_Keyword;
4320 }
4321 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004322 CXTok.int_data[0] = Tok.is(tok::identifier)
4323 ? CXToken_Identifier
4324 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004325 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004326 CXTok.ptr_data = II;
4327 } else if (Tok.is(tok::comment)) {
4328 CXTok.int_data[0] = CXToken_Comment;
4329 CXTok.ptr_data = 0;
4330 } else {
4331 CXTok.int_data[0] = CXToken_Punctuation;
4332 CXTok.ptr_data = 0;
4333 }
4334 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004335 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004336 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004337
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004338 if (CXTokens.empty())
4339 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004340
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004341 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4342 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4343 *NumTokens = CXTokens.size();
4344}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004345
Ted Kremenek6db61092010-05-05 00:55:15 +00004346void clang_disposeTokens(CXTranslationUnit TU,
4347 CXToken *Tokens, unsigned NumTokens) {
4348 free(Tokens);
4349}
4350
4351} // end: extern "C"
4352
4353//===----------------------------------------------------------------------===//
4354// Token annotation APIs.
4355//===----------------------------------------------------------------------===//
4356
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004357typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004358static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4359 CXCursor parent,
4360 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004361namespace {
4362class AnnotateTokensWorker {
4363 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004364 CXToken *Tokens;
4365 CXCursor *Cursors;
4366 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004367 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004368 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004369 CursorVisitor AnnotateVis;
4370 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004371 bool HasContextSensitiveKeywords;
4372
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004373 bool MoreTokens() const { return TokIdx < NumTokens; }
4374 unsigned NextToken() const { return TokIdx; }
4375 void AdvanceToken() { ++TokIdx; }
4376 SourceLocation GetTokenLoc(unsigned tokI) {
4377 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4378 }
4379
Ted Kremenek6db61092010-05-05 00:55:15 +00004380public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004381 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004382 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004383 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004384 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004385 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004386 AnnotateVis(tu,
4387 AnnotateTokensVisitor, this,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00004388 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004389 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4390 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004391
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004392 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004393 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004394 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004395 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004396 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004397 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004398
4399 /// \brief Determine whether the annotator saw any cursors that have
4400 /// context-sensitive keywords.
4401 bool hasContextSensitiveKeywords() const {
4402 return HasContextSensitiveKeywords;
4403 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004404};
4405}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004406
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004407void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4408 // Walk the AST within the region of interest, annotating tokens
4409 // along the way.
4410 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004411
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004412 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4413 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004414 if (Pos != Annotated.end() &&
4415 (clang_isInvalid(Cursors[I].kind) ||
4416 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004417 Cursors[I] = Pos->second;
4418 }
4419
4420 // Finish up annotating any tokens left.
4421 if (!MoreTokens())
4422 return;
4423
4424 const CXCursor &C = clang_getNullCursor();
4425 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4426 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4427 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004428 }
4429}
4430
Ted Kremenek6db61092010-05-05 00:55:15 +00004431enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004432AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004433 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004434 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004435 if (cursorRange.isInvalid())
4436 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004437
4438 if (!HasContextSensitiveKeywords) {
4439 // Objective-C properties can have context-sensitive keywords.
4440 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4441 if (ObjCPropertyDecl *Property
4442 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4443 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4444 }
4445 // Objective-C methods can have context-sensitive keywords.
4446 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4447 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4448 if (ObjCMethodDecl *Method
4449 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4450 if (Method->getObjCDeclQualifier())
4451 HasContextSensitiveKeywords = true;
4452 else {
4453 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4454 PEnd = Method->param_end();
4455 P != PEnd; ++P) {
4456 if ((*P)->getObjCDeclQualifier()) {
4457 HasContextSensitiveKeywords = true;
4458 break;
4459 }
4460 }
4461 }
4462 }
4463 }
4464 // C++ methods can have context-sensitive keywords.
4465 else if (cursor.kind == CXCursor_CXXMethod) {
4466 if (CXXMethodDecl *Method
4467 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4468 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4469 HasContextSensitiveKeywords = true;
4470 }
4471 }
4472 // C++ classes can have context-sensitive keywords.
4473 else if (cursor.kind == CXCursor_StructDecl ||
4474 cursor.kind == CXCursor_ClassDecl ||
4475 cursor.kind == CXCursor_ClassTemplate ||
4476 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4477 if (Decl *D = getCursorDecl(cursor))
4478 if (D->hasAttr<FinalAttr>())
4479 HasContextSensitiveKeywords = true;
4480 }
4481 }
4482
Douglas Gregor4419b672010-10-21 06:10:04 +00004483 if (clang_isPreprocessing(cursor.kind)) {
4484 // For macro instantiations, just note where the beginning of the macro
4485 // instantiation occurs.
4486 if (cursor.kind == CXCursor_MacroInstantiation) {
4487 Annotated[Loc.int_data] = cursor;
4488 return CXChildVisit_Recurse;
4489 }
4490
Douglas Gregor4419b672010-10-21 06:10:04 +00004491 // Items in the preprocessing record are kept separate from items in
4492 // declarations, so we keep a separate token index.
4493 unsigned SavedTokIdx = TokIdx;
4494 TokIdx = PreprocessingTokIdx;
4495
4496 // Skip tokens up until we catch up to the beginning of the preprocessing
4497 // entry.
4498 while (MoreTokens()) {
4499 const unsigned I = NextToken();
4500 SourceLocation TokLoc = GetTokenLoc(I);
4501 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4502 case RangeBefore:
4503 AdvanceToken();
4504 continue;
4505 case RangeAfter:
4506 case RangeOverlap:
4507 break;
4508 }
4509 break;
4510 }
4511
4512 // Look at all of the tokens within this range.
4513 while (MoreTokens()) {
4514 const unsigned I = NextToken();
4515 SourceLocation TokLoc = GetTokenLoc(I);
4516 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4517 case RangeBefore:
4518 assert(0 && "Infeasible");
4519 case RangeAfter:
4520 break;
4521 case RangeOverlap:
4522 Cursors[I] = cursor;
4523 AdvanceToken();
4524 continue;
4525 }
4526 break;
4527 }
4528
4529 // Save the preprocessing token index; restore the non-preprocessing
4530 // token index.
4531 PreprocessingTokIdx = TokIdx;
4532 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004533 return CXChildVisit_Recurse;
4534 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004535
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004536 if (cursorRange.isInvalid())
4537 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004538
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004539 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4540
Ted Kremeneka333c662010-05-12 05:29:33 +00004541 // Adjust the annotated range based specific declarations.
4542 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4543 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004544 Decl *D = cxcursor::getCursorDecl(cursor);
4545 // Don't visit synthesized ObjC methods, since they have no syntatic
4546 // representation in the source.
4547 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4548 if (MD->isSynthesized())
4549 return CXChildVisit_Continue;
4550 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004551
4552 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004553 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004554 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4555 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4556 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4557 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4558 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004559 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004560
4561 if (StartLoc.isValid() && L.isValid() &&
4562 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4563 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004564 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004565
Ted Kremenek3f404602010-08-14 01:14:06 +00004566 // If the location of the cursor occurs within a macro instantiation, record
4567 // the spelling location of the cursor in our annotation map. We can then
4568 // paper over the token labelings during a post-processing step to try and
4569 // get cursor mappings for tokens that are the *arguments* of a macro
4570 // instantiation.
4571 if (L.isMacroID()) {
4572 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4573 // Only invalidate the old annotation if it isn't part of a preprocessing
4574 // directive. Here we assume that the default construction of CXCursor
4575 // results in CXCursor.kind being an initialized value (i.e., 0). If
4576 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004577
Ted Kremenek3f404602010-08-14 01:14:06 +00004578 CXCursor &oldC = Annotated[rawEncoding];
4579 if (!clang_isPreprocessing(oldC.kind))
4580 oldC = cursor;
4581 }
4582
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004583 const enum CXCursorKind K = clang_getCursorKind(parent);
4584 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004585 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4586 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004587
4588 while (MoreTokens()) {
4589 const unsigned I = NextToken();
4590 SourceLocation TokLoc = GetTokenLoc(I);
4591 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4592 case RangeBefore:
4593 Cursors[I] = updateC;
4594 AdvanceToken();
4595 continue;
4596 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004597 case RangeOverlap:
4598 break;
4599 }
4600 break;
4601 }
4602
4603 // Visit children to get their cursor information.
4604 const unsigned BeforeChildren = NextToken();
4605 VisitChildren(cursor);
4606 const unsigned AfterChildren = NextToken();
4607
4608 // Adjust 'Last' to the last token within the extent of the cursor.
4609 while (MoreTokens()) {
4610 const unsigned I = NextToken();
4611 SourceLocation TokLoc = GetTokenLoc(I);
4612 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4613 case RangeBefore:
4614 assert(0 && "Infeasible");
4615 case RangeAfter:
4616 break;
4617 case RangeOverlap:
4618 Cursors[I] = updateC;
4619 AdvanceToken();
4620 continue;
4621 }
4622 break;
4623 }
4624 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004625
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004626 // Scan the tokens that are at the beginning of the cursor, but are not
4627 // capture by the child cursors.
4628
4629 // For AST elements within macros, rely on a post-annotate pass to
4630 // to correctly annotate the tokens with cursors. Otherwise we can
4631 // get confusing results of having tokens that map to cursors that really
4632 // are expanded by an instantiation.
4633 if (L.isMacroID())
4634 cursor = clang_getNullCursor();
4635
4636 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4637 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4638 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004639
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004640 Cursors[I] = cursor;
4641 }
4642 // Scan the tokens that are at the end of the cursor, but are not captured
4643 // but the child cursors.
4644 for (unsigned I = AfterChildren; I != Last; ++I)
4645 Cursors[I] = cursor;
4646
4647 TokIdx = Last;
4648 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004649}
4650
Ted Kremenek6db61092010-05-05 00:55:15 +00004651static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4652 CXCursor parent,
4653 CXClientData client_data) {
4654 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4655}
4656
Ted Kremenek6628a612011-03-18 22:51:30 +00004657namespace {
4658 struct clang_annotateTokens_Data {
4659 CXTranslationUnit TU;
4660 ASTUnit *CXXUnit;
4661 CXToken *Tokens;
4662 unsigned NumTokens;
4663 CXCursor *Cursors;
4664 };
4665}
4666
Ted Kremenekab979612010-11-11 08:05:23 +00004667// This gets run a separate thread to avoid stack blowout.
Ted Kremenek6628a612011-03-18 22:51:30 +00004668static void clang_annotateTokensImpl(void *UserData) {
4669 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4670 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4671 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4672 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4673 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4674
4675 // Determine the region of interest, which contains all of the tokens.
4676 SourceRange RegionOfInterest;
4677 RegionOfInterest.setBegin(
4678 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4679 RegionOfInterest.setEnd(
4680 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4681 Tokens[NumTokens-1])));
4682
4683 // A mapping from the source locations found when re-lexing or traversing the
4684 // region of interest to the corresponding cursors.
4685 AnnotateTokensData Annotated;
4686
4687 // Relex the tokens within the source range to look for preprocessing
4688 // directives.
4689 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4690 std::pair<FileID, unsigned> BeginLocInfo
4691 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4692 std::pair<FileID, unsigned> EndLocInfo
4693 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4694
4695 llvm::StringRef Buffer;
4696 bool Invalid = false;
4697 if (BeginLocInfo.first == EndLocInfo.first &&
4698 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4699 !Invalid) {
4700 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4701 CXXUnit->getASTContext().getLangOptions(),
4702 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4703 Buffer.end());
4704 Lex.SetCommentRetentionState(true);
4705
4706 // Lex tokens in raw mode until we hit the end of the range, to avoid
4707 // entering #includes or expanding macros.
4708 while (true) {
4709 Token Tok;
4710 Lex.LexFromRawLexer(Tok);
4711
4712 reprocess:
4713 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4714 // We have found a preprocessing directive. Gobble it up so that we
4715 // don't see it while preprocessing these tokens later, but keep track
4716 // of all of the token locations inside this preprocessing directive so
4717 // that we can annotate them appropriately.
4718 //
4719 // FIXME: Some simple tests here could identify macro definitions and
4720 // #undefs, to provide specific cursor kinds for those.
4721 llvm::SmallVector<SourceLocation, 32> Locations;
4722 do {
4723 Locations.push_back(Tok.getLocation());
4724 Lex.LexFromRawLexer(Tok);
4725 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4726
4727 using namespace cxcursor;
4728 CXCursor Cursor
4729 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4730 Locations.back()),
4731 TU);
4732 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4733 Annotated[Locations[I].getRawEncoding()] = Cursor;
4734 }
4735
4736 if (Tok.isAtStartOfLine())
4737 goto reprocess;
4738
4739 continue;
4740 }
4741
4742 if (Tok.is(tok::eof))
4743 break;
4744 }
4745 }
4746
4747 // Annotate all of the source locations in the region of interest that map to
4748 // a specific cursor.
4749 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4750 TU, RegionOfInterest);
4751
4752 // FIXME: We use a ridiculous stack size here because the data-recursion
4753 // algorithm uses a large stack frame than the non-data recursive version,
4754 // and AnnotationTokensWorker currently transforms the data-recursion
4755 // algorithm back into a traditional recursion by explicitly calling
4756 // VisitChildren(). We will need to remove this explicit recursive call.
4757 W.AnnotateTokens();
4758
4759 // If we ran into any entities that involve context-sensitive keywords,
4760 // take another pass through the tokens to mark them as such.
4761 if (W.hasContextSensitiveKeywords()) {
4762 for (unsigned I = 0; I != NumTokens; ++I) {
4763 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4764 continue;
4765
4766 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4767 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4768 if (ObjCPropertyDecl *Property
4769 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4770 if (Property->getPropertyAttributesAsWritten() != 0 &&
4771 llvm::StringSwitch<bool>(II->getName())
4772 .Case("readonly", true)
4773 .Case("assign", true)
4774 .Case("readwrite", true)
4775 .Case("retain", true)
4776 .Case("copy", true)
4777 .Case("nonatomic", true)
4778 .Case("atomic", true)
4779 .Case("getter", true)
4780 .Case("setter", true)
4781 .Default(false))
4782 Tokens[I].int_data[0] = CXToken_Keyword;
4783 }
4784 continue;
4785 }
4786
4787 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4788 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4789 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4790 if (llvm::StringSwitch<bool>(II->getName())
4791 .Case("in", true)
4792 .Case("out", true)
4793 .Case("inout", true)
4794 .Case("oneway", true)
4795 .Case("bycopy", true)
4796 .Case("byref", true)
4797 .Default(false))
4798 Tokens[I].int_data[0] = CXToken_Keyword;
4799 continue;
4800 }
4801
4802 if (Cursors[I].kind == CXCursor_CXXMethod) {
4803 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4804 if (CXXMethodDecl *Method
4805 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4806 if ((Method->hasAttr<FinalAttr>() ||
4807 Method->hasAttr<OverrideAttr>()) &&
4808 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4809 llvm::StringSwitch<bool>(II->getName())
4810 .Case("final", true)
4811 .Case("override", true)
4812 .Default(false))
4813 Tokens[I].int_data[0] = CXToken_Keyword;
4814 }
4815 continue;
4816 }
4817
4818 if (Cursors[I].kind == CXCursor_ClassDecl ||
4819 Cursors[I].kind == CXCursor_StructDecl ||
4820 Cursors[I].kind == CXCursor_ClassTemplate) {
4821 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4822 if (II->getName() == "final") {
4823 // We have to be careful with 'final', since it could be the name
4824 // of a member class rather than the context-sensitive keyword.
4825 // So, check whether the cursor associated with this
4826 Decl *D = getCursorDecl(Cursors[I]);
4827 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4828 if ((Record->hasAttr<FinalAttr>()) &&
4829 Record->getIdentifier() != II)
4830 Tokens[I].int_data[0] = CXToken_Keyword;
4831 } else if (ClassTemplateDecl *ClassTemplate
4832 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4833 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4834 if ((Record->hasAttr<FinalAttr>()) &&
4835 Record->getIdentifier() != II)
4836 Tokens[I].int_data[0] = CXToken_Keyword;
4837 }
4838 }
4839 continue;
4840 }
4841 }
4842 }
Ted Kremenekab979612010-11-11 08:05:23 +00004843}
4844
Ted Kremenek6db61092010-05-05 00:55:15 +00004845extern "C" {
4846
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004847void clang_annotateTokens(CXTranslationUnit TU,
4848 CXToken *Tokens, unsigned NumTokens,
4849 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004850
4851 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004852 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004853
Douglas Gregor4419b672010-10-21 06:10:04 +00004854 // Any token we don't specifically annotate will have a NULL cursor.
4855 CXCursor C = clang_getNullCursor();
4856 for (unsigned I = 0; I != NumTokens; ++I)
4857 Cursors[I] = C;
4858
Ted Kremeneka60ed472010-11-16 08:15:36 +00004859 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004860 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004861 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004862
Douglas Gregorbdf60622010-03-05 21:16:25 +00004863 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek6628a612011-03-18 22:51:30 +00004864
4865 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekab979612010-11-11 08:05:23 +00004866 llvm::CrashRecoveryContext CRC;
Ted Kremenek6628a612011-03-18 22:51:30 +00004867 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004868 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004869 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4870 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004871}
Ted Kremenek6628a612011-03-18 22:51:30 +00004872
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004873} // end: extern "C"
4874
4875//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004876// Operations for querying linkage of a cursor.
4877//===----------------------------------------------------------------------===//
4878
4879extern "C" {
4880CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004881 if (!clang_isDeclaration(cursor.kind))
4882 return CXLinkage_Invalid;
4883
Ted Kremenek16b42592010-03-03 06:36:57 +00004884 Decl *D = cxcursor::getCursorDecl(cursor);
4885 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4886 switch (ND->getLinkage()) {
4887 case NoLinkage: return CXLinkage_NoLinkage;
4888 case InternalLinkage: return CXLinkage_Internal;
4889 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4890 case ExternalLinkage: return CXLinkage_External;
4891 };
4892
4893 return CXLinkage_Invalid;
4894}
4895} // end: extern "C"
4896
4897//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004898// Operations for querying language of a cursor.
4899//===----------------------------------------------------------------------===//
4900
4901static CXLanguageKind getDeclLanguage(const Decl *D) {
4902 switch (D->getKind()) {
4903 default:
4904 break;
4905 case Decl::ImplicitParam:
4906 case Decl::ObjCAtDefsField:
4907 case Decl::ObjCCategory:
4908 case Decl::ObjCCategoryImpl:
4909 case Decl::ObjCClass:
4910 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004911 case Decl::ObjCForwardProtocol:
4912 case Decl::ObjCImplementation:
4913 case Decl::ObjCInterface:
4914 case Decl::ObjCIvar:
4915 case Decl::ObjCMethod:
4916 case Decl::ObjCProperty:
4917 case Decl::ObjCPropertyImpl:
4918 case Decl::ObjCProtocol:
4919 return CXLanguage_ObjC;
4920 case Decl::CXXConstructor:
4921 case Decl::CXXConversion:
4922 case Decl::CXXDestructor:
4923 case Decl::CXXMethod:
4924 case Decl::CXXRecord:
4925 case Decl::ClassTemplate:
4926 case Decl::ClassTemplatePartialSpecialization:
4927 case Decl::ClassTemplateSpecialization:
4928 case Decl::Friend:
4929 case Decl::FriendTemplate:
4930 case Decl::FunctionTemplate:
4931 case Decl::LinkageSpec:
4932 case Decl::Namespace:
4933 case Decl::NamespaceAlias:
4934 case Decl::NonTypeTemplateParm:
4935 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004936 case Decl::TemplateTemplateParm:
4937 case Decl::TemplateTypeParm:
4938 case Decl::UnresolvedUsingTypename:
4939 case Decl::UnresolvedUsingValue:
4940 case Decl::Using:
4941 case Decl::UsingDirective:
4942 case Decl::UsingShadow:
4943 return CXLanguage_CPlusPlus;
4944 }
4945
4946 return CXLanguage_C;
4947}
4948
4949extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004950
4951enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4952 if (clang_isDeclaration(cursor.kind))
4953 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004954 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregor58ddb602010-08-23 23:00:57 +00004955 return CXAvailability_Available;
4956
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004957 switch (D->getAvailability()) {
4958 case AR_Available:
4959 case AR_NotYetIntroduced:
4960 return CXAvailability_Available;
4961
4962 case AR_Deprecated:
Douglas Gregor58ddb602010-08-23 23:00:57 +00004963 return CXAvailability_Deprecated;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004964
4965 case AR_Unavailable:
4966 return CXAvailability_NotAvailable;
4967 }
Douglas Gregor58ddb602010-08-23 23:00:57 +00004968 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004969
Douglas Gregor58ddb602010-08-23 23:00:57 +00004970 return CXAvailability_Available;
4971}
4972
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004973CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4974 if (clang_isDeclaration(cursor.kind))
4975 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4976
4977 return CXLanguage_Invalid;
4978}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004979
4980 /// \brief If the given cursor is the "templated" declaration
4981 /// descibing a class or function template, return the class or
4982 /// function template.
4983static Decl *maybeGetTemplateCursor(Decl *D) {
4984 if (!D)
4985 return 0;
4986
4987 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4988 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4989 return FunTmpl;
4990
4991 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4992 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4993 return ClassTmpl;
4994
4995 return D;
4996}
4997
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004998CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4999 if (clang_isDeclaration(cursor.kind)) {
5000 if (Decl *D = getCursorDecl(cursor)) {
5001 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00005002 if (!DC)
5003 return clang_getNullCursor();
5004
5005 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5006 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005007 }
5008 }
5009
5010 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
5011 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00005012 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005013 }
5014
5015 return clang_getNullCursor();
5016}
5017
5018CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5019 if (clang_isDeclaration(cursor.kind)) {
5020 if (Decl *D = getCursorDecl(cursor)) {
5021 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00005022 if (!DC)
5023 return clang_getNullCursor();
5024
5025 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5026 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005027 }
5028 }
5029
5030 // FIXME: Note that we can't easily compute the lexical context of a
5031 // statement or expression, so we return nothing.
5032 return clang_getNullCursor();
5033}
5034
Douglas Gregor9f592342010-10-01 20:25:15 +00005035static void CollectOverriddenMethods(DeclContext *Ctx,
5036 ObjCMethodDecl *Method,
5037 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5038 if (!Ctx)
5039 return;
5040
5041 // If we have a class or category implementation, jump straight to the
5042 // interface.
5043 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5044 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5045
5046 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5047 if (!Container)
5048 return;
5049
5050 // Check whether we have a matching method at this level.
5051 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5052 Method->isInstanceMethod()))
5053 if (Method != Overridden) {
5054 // We found an override at this level; there is no need to look
5055 // into other protocols or categories.
5056 Methods.push_back(Overridden);
5057 return;
5058 }
5059
5060 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5061 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5062 PEnd = Protocol->protocol_end();
5063 P != PEnd; ++P)
5064 CollectOverriddenMethods(*P, Method, Methods);
5065 }
5066
5067 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5068 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5069 PEnd = Category->protocol_end();
5070 P != PEnd; ++P)
5071 CollectOverriddenMethods(*P, Method, Methods);
5072 }
5073
5074 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5075 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5076 PEnd = Interface->protocol_end();
5077 P != PEnd; ++P)
5078 CollectOverriddenMethods(*P, Method, Methods);
5079
5080 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5081 Category; Category = Category->getNextClassCategory())
5082 CollectOverriddenMethods(Category, Method, Methods);
5083
5084 // We only look into the superclass if we haven't found anything yet.
5085 if (Methods.empty())
5086 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5087 return CollectOverriddenMethods(Super, Method, Methods);
5088 }
5089}
5090
5091void clang_getOverriddenCursors(CXCursor cursor,
5092 CXCursor **overridden,
5093 unsigned *num_overridden) {
5094 if (overridden)
5095 *overridden = 0;
5096 if (num_overridden)
5097 *num_overridden = 0;
5098 if (!overridden || !num_overridden)
5099 return;
5100
5101 if (!clang_isDeclaration(cursor.kind))
5102 return;
5103
5104 Decl *D = getCursorDecl(cursor);
5105 if (!D)
5106 return;
5107
5108 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00005109 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00005110 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5111 *num_overridden = CXXMethod->size_overridden_methods();
5112 if (!*num_overridden)
5113 return;
5114
5115 *overridden = new CXCursor [*num_overridden];
5116 unsigned I = 0;
5117 for (CXXMethodDecl::method_iterator
5118 M = CXXMethod->begin_overridden_methods(),
5119 MEnd = CXXMethod->end_overridden_methods();
5120 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005121 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005122 return;
5123 }
5124
5125 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5126 if (!Method)
5127 return;
5128
5129 // Handle Objective-C methods.
5130 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5131 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5132
5133 if (Methods.empty())
5134 return;
5135
5136 *num_overridden = Methods.size();
5137 *overridden = new CXCursor [Methods.size()];
5138 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005139 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005140}
5141
5142void clang_disposeOverriddenCursors(CXCursor *overridden) {
5143 delete [] overridden;
5144}
5145
Douglas Gregorecdcb882010-10-20 22:00:55 +00005146CXFile clang_getIncludedFile(CXCursor cursor) {
5147 if (cursor.kind != CXCursor_InclusionDirective)
5148 return 0;
5149
5150 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5151 return (void *)ID->getFile();
5152}
5153
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005154} // end: extern "C"
5155
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005156
5157//===----------------------------------------------------------------------===//
5158// C++ AST instrospection.
5159//===----------------------------------------------------------------------===//
5160
5161extern "C" {
5162unsigned clang_CXXMethod_isStatic(CXCursor C) {
5163 if (!clang_isDeclaration(C.kind))
5164 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005165
5166 CXXMethodDecl *Method = 0;
5167 Decl *D = cxcursor::getCursorDecl(C);
5168 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5169 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5170 else
5171 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5172 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005173}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005174
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005175} // end: extern "C"
5176
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005177//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005178// Attribute introspection.
5179//===----------------------------------------------------------------------===//
5180
5181extern "C" {
5182CXType clang_getIBOutletCollectionType(CXCursor C) {
5183 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005184 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005185
5186 IBOutletCollectionAttr *A =
5187 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5188
Douglas Gregor841b2382011-03-06 18:55:32 +00005189 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005190}
5191} // end: extern "C"
5192
5193//===----------------------------------------------------------------------===//
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005194// Inspecting memory usage.
5195//===----------------------------------------------------------------------===//
5196
Ted Kremenekf7870022011-04-20 16:41:07 +00005197typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005198
Ted Kremenekf7870022011-04-20 16:41:07 +00005199static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
5200 enum CXTUResourceUsageKind k,
Ted Kremenekba29bd22011-04-28 04:53:38 +00005201 unsigned long amount) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005202 CXTUResourceUsageEntry entry = { k, amount };
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005203 entries.push_back(entry);
5204}
5205
5206extern "C" {
5207
Ted Kremenekf7870022011-04-20 16:41:07 +00005208const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005209 const char *str = "";
5210 switch (kind) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005211 case CXTUResourceUsage_AST:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005212 str = "ASTContext: expressions, declarations, and types";
5213 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005214 case CXTUResourceUsage_Identifiers:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005215 str = "ASTContext: identifiers";
5216 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005217 case CXTUResourceUsage_Selectors:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005218 str = "ASTContext: selectors";
Ted Kremeneke294ab72011-04-19 04:36:17 +00005219 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005220 case CXTUResourceUsage_GlobalCompletionResults:
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005221 str = "Code completion: cached global results";
Ted Kremeneke294ab72011-04-19 04:36:17 +00005222 break;
Ted Kremenek457aaf02011-04-28 04:10:31 +00005223 case CXTUResourceUsage_SourceManagerContentCache:
5224 str = "SourceManager: content cache allocator";
5225 break;
Ted Kremenekba29bd22011-04-28 04:53:38 +00005226 case CXTUResourceUsage_AST_SideTables:
5227 str = "ASTContext: side tables";
5228 break;
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005229 }
5230 return str;
5231}
5232
Ted Kremenekf7870022011-04-20 16:41:07 +00005233CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005234 if (!TU) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005235 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005236 return usage;
5237 }
5238
5239 ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
5240 llvm::OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
5241 ASTContext &astContext = astUnit->getASTContext();
5242
5243 // How much memory is used by AST nodes and types?
Ted Kremenekf7870022011-04-20 16:41:07 +00005244 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
Ted Kremenekba29bd22011-04-28 04:53:38 +00005245 (unsigned long) astContext.getASTAllocatedMemory());
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005246
5247 // How much memory is used by identifiers?
Ted Kremenekf7870022011-04-20 16:41:07 +00005248 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005249 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
5250
5251 // How much memory is used for selectors?
Ted Kremenekf7870022011-04-20 16:41:07 +00005252 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005253 (unsigned long) astContext.Selectors.getTotalMemory());
5254
Ted Kremenekba29bd22011-04-28 04:53:38 +00005255 // How much memory is used by ASTContext's side tables?
5256 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
5257 (unsigned long) astContext.getSideTableAllocatedMemory());
5258
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005259 // How much memory is used for caching global code completion results?
5260 unsigned long completionBytes = 0;
5261 if (GlobalCodeCompletionAllocator *completionAllocator =
5262 astUnit->getCachedCompletionAllocator().getPtr()) {
5263 completionBytes = completionAllocator-> getTotalMemory();
5264 }
Ted Kremenek457aaf02011-04-28 04:10:31 +00005265 createCXTUResourceUsageEntry(*entries,
5266 CXTUResourceUsage_GlobalCompletionResults,
5267 completionBytes);
5268
5269 // How much memory is being used by SourceManager's content cache?
5270 createCXTUResourceUsageEntry(*entries,
5271 CXTUResourceUsage_SourceManagerContentCache,
5272 (unsigned long) astContext.getSourceManager().getContentCacheSize());
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005273
5274
Ted Kremenekf7870022011-04-20 16:41:07 +00005275 CXTUResourceUsage usage = { (void*) entries.get(),
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005276 (unsigned) entries->size(),
5277 entries->size() ? &(*entries)[0] : 0 };
5278 entries.take();
5279 return usage;
5280}
5281
Ted Kremenekf7870022011-04-20 16:41:07 +00005282void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005283 if (usage.data)
5284 delete (MemUsageEntries*) usage.data;
5285}
5286
5287} // end extern "C"
5288
5289//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005290// Misc. utility functions.
5291//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005292
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005293/// Default to using an 8 MB stack size on "safety" threads.
5294static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005295
5296namespace clang {
5297
5298bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005299 void (*Fn)(void*), void *UserData,
5300 unsigned Size) {
5301 if (!Size)
5302 Size = GetSafetyThreadStackSize();
5303 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005304 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5305 return CRC.RunSafely(Fn, UserData);
5306}
5307
5308unsigned GetSafetyThreadStackSize() {
5309 return SafetyStackThreadSize;
5310}
5311
5312void SetSafetyThreadStackSize(unsigned Value) {
5313 SafetyStackThreadSize = Value;
5314}
5315
5316}
5317
Ted Kremenek04bb7162010-01-22 22:44:15 +00005318extern "C" {
5319
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005320CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005321 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005322}
5323
5324} // end: extern "C"
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005325