blob: a50c987b3c25b86951ab4f188a0cb08fe348ad03 [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:
1415 case BuiltinType::Dependent:
John McCall1de4d4e2011-04-07 08:22:57 +00001416 case BuiltinType::UnknownAny:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001417 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001418
Ted Kremenekc4174cc2010-02-18 18:52:18 +00001419 case BuiltinType::ObjCId:
1420 VisitType = Context.getObjCIdType();
1421 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001422
1423 case BuiltinType::ObjCClass:
1424 VisitType = Context.getObjCClassType();
1425 break;
1426
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001427 case BuiltinType::ObjCSel:
1428 VisitType = Context.getObjCSelType();
1429 break;
1430 }
1431
1432 if (!VisitType.isNull()) {
1433 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001434 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001435 TU));
1436 }
1437
1438 return false;
1439}
1440
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001441bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
Richard Smith162e1c12011-04-15 14:24:37 +00001442 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001443}
1444
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001445bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1446 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1447}
1448
1449bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1450 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1451}
1452
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001453bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001454 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001455 // no context information with which we can match up the depth/index in the
1456 // type to the appropriate
1457 return false;
1458}
1459
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001460bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1461 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1462 return true;
1463
John McCallc12c5bb2010-05-15 11:32:37 +00001464 return false;
1465}
1466
1467bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1468 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1469 return true;
1470
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001471 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1472 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1473 TU)))
1474 return true;
1475 }
1476
1477 return false;
1478}
1479
1480bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCallc12c5bb2010-05-15 11:32:37 +00001481 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001482}
1483
Abramo Bagnara075f8f12010-12-10 16:29:40 +00001484bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1485 return Visit(TL.getInnerLoc());
1486}
1487
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001488bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1489 return Visit(TL.getPointeeLoc());
1490}
1491
1492bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1493 return Visit(TL.getPointeeLoc());
1494}
1495
1496bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1497 return Visit(TL.getPointeeLoc());
1498}
1499
1500bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001501 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001502}
1503
1504bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001505 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001506}
1507
Douglas Gregor01829d32010-08-31 14:41:23 +00001508bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1509 bool SkipResultType) {
1510 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001511 return true;
1512
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001513 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek5dbacb42010-04-07 00:27:13 +00001514 if (Decl *D = TL.getArg(I))
1515 if (Visit(MakeCXCursor(D, TU)))
1516 return true;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001517
1518 return false;
1519}
1520
1521bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1522 if (Visit(TL.getElementLoc()))
1523 return true;
1524
1525 if (Expr *Size = TL.getSizeExpr())
1526 return Visit(MakeCXCursor(Size, StmtParent, TU));
1527
1528 return false;
1529}
1530
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001531bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1532 TemplateSpecializationTypeLoc TL) {
Douglas Gregor0b36e612010-08-31 20:37:03 +00001533 // Visit the template name.
1534 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1535 TL.getTemplateNameLoc()))
1536 return true;
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001537
1538 // Visit the template arguments.
1539 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1540 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1541 return true;
1542
1543 return false;
1544}
1545
Douglas Gregor2332c112010-01-21 20:48:56 +00001546bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1547 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1548}
1549
1550bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1551 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1552 return Visit(TSInfo->getTypeLoc());
1553
1554 return false;
1555}
1556
Douglas Gregor2494dd02011-03-01 01:34:45 +00001557bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1558 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1559 return true;
1560
1561 return false;
1562}
1563
Douglas Gregor94fdffa2011-03-01 20:11:18 +00001564bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1565 DependentTemplateSpecializationTypeLoc TL) {
1566 // Visit the nested-name-specifier, if there is one.
1567 if (TL.getQualifierLoc() &&
1568 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1569 return true;
1570
1571 // Visit the template arguments.
1572 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1573 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1574 return true;
1575
1576 return false;
1577}
1578
Douglas Gregor9e876872011-03-01 18:12:44 +00001579bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1580 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1581 return true;
1582
1583 return Visit(TL.getNamedTypeLoc());
1584}
1585
Douglas Gregor7536dd52010-12-20 02:24:11 +00001586bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1587 return Visit(TL.getPatternLoc());
1588}
1589
Ted Kremenek3064ef92010-08-27 21:34:58 +00001590bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001591 // Visit the nested-name-specifier, if present.
1592 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1593 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1594 return true;
1595
Ted Kremenek3064ef92010-08-27 21:34:58 +00001596 if (D->isDefinition()) {
1597 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1598 E = D->bases_end(); I != E; ++I) {
1599 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1600 return true;
1601 }
1602 }
1603
1604 return VisitTagDecl(D);
1605}
1606
Ted Kremenek09dfa372010-02-18 05:46:33 +00001607bool CursorVisitor::VisitAttributes(Decl *D) {
Sean Huntcf807c42010-08-18 23:23:40 +00001608 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1609 i != e; ++i)
1610 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek09dfa372010-02-18 05:46:33 +00001611 return true;
1612
1613 return false;
1614}
1615
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001616//===----------------------------------------------------------------------===//
1617// Data-recursive visitor methods.
1618//===----------------------------------------------------------------------===//
1619
Ted Kremenek28a71942010-11-13 00:36:47 +00001620namespace {
Ted Kremenek035dc412010-11-13 00:36:50 +00001621#define DEF_JOB(NAME, DATA, KIND)\
1622class NAME : public VisitorJob {\
1623public:\
1624 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1625 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenekf64d8032010-11-18 00:02:32 +00001626 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek035dc412010-11-13 00:36:50 +00001627};
1628
1629DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1630DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001631DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001632DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek60608ec2010-11-17 00:50:47 +00001633DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1634 ExplicitTemplateArgsVisitKind)
Douglas Gregor94d96292011-01-19 20:34:17 +00001635DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001636#undef DEF_JOB
1637
1638class DeclVisit : public VisitorJob {
1639public:
1640 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1641 VisitorJob(parent, VisitorJob::DeclVisitKind,
1642 d, isFirst ? (void*) 1 : (void*) 0) {}
1643 static bool classof(const VisitorJob *VJ) {
Ted Kremenek82f3c502010-11-15 22:23:26 +00001644 return VJ->getKind() == DeclVisitKind;
Ted Kremenek035dc412010-11-13 00:36:50 +00001645 }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001646 Decl *get() const { return static_cast<Decl*>(data[0]); }
1647 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek035dc412010-11-13 00:36:50 +00001648};
Ted Kremenek035dc412010-11-13 00:36:50 +00001649class TypeLocVisit : public VisitorJob {
1650public:
1651 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1652 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1653 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1654
1655 static bool classof(const VisitorJob *VJ) {
1656 return VJ->getKind() == TypeLocVisitKind;
1657 }
1658
Ted Kremenek82f3c502010-11-15 22:23:26 +00001659 TypeLoc get() const {
Ted Kremenekf64d8032010-11-18 00:02:32 +00001660 QualType T = QualType::getFromOpaquePtr(data[0]);
1661 return TypeLoc(T, data[1]);
Ted Kremenek035dc412010-11-13 00:36:50 +00001662 }
1663};
1664
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001665class LabelRefVisit : public VisitorJob {
1666public:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001667 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1668 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001669 labelLoc.getPtrEncoding()) {}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001670
1671 static bool classof(const VisitorJob *VJ) {
1672 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1673 }
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001674 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001675 SourceLocation getLoc() const {
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001676 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001677};
1678class NestedNameSpecifierVisit : public VisitorJob {
1679public:
1680 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1681 CXCursor parent)
1682 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001683 NS, R.getBegin().getPtrEncoding(),
1684 R.getEnd().getPtrEncoding()) {}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001685 static bool classof(const VisitorJob *VJ) {
1686 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1687 }
1688 NestedNameSpecifier *get() const {
1689 return static_cast<NestedNameSpecifier*>(data[0]);
1690 }
1691 SourceRange getSourceRange() const {
1692 SourceLocation A =
1693 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1694 SourceLocation B =
1695 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1696 return SourceRange(A, B);
1697 }
1698};
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001699
1700class NestedNameSpecifierLocVisit : public VisitorJob {
1701public:
1702 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1703 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1704 Qualifier.getNestedNameSpecifier(),
1705 Qualifier.getOpaqueData()) { }
1706
1707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1709 }
1710
1711 NestedNameSpecifierLoc get() const {
1712 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1713 data[1]);
1714 }
1715};
1716
Ted Kremenekf64d8032010-11-18 00:02:32 +00001717class DeclarationNameInfoVisit : public VisitorJob {
1718public:
1719 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1720 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1721 static bool classof(const VisitorJob *VJ) {
1722 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1723 }
1724 DeclarationNameInfo get() const {
1725 Stmt *S = static_cast<Stmt*>(data[0]);
1726 switch (S->getStmtClass()) {
1727 default:
1728 llvm_unreachable("Unhandled Stmt");
1729 case Stmt::CXXDependentScopeMemberExprClass:
1730 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1731 case Stmt::DependentScopeDeclRefExprClass:
1732 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1733 }
1734 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001735};
Ted Kremenekcdba6592010-11-18 00:42:18 +00001736class MemberRefVisit : public VisitorJob {
1737public:
1738 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1739 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001740 L.getPtrEncoding()) {}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001741 static bool classof(const VisitorJob *VJ) {
1742 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1743 }
1744 FieldDecl *get() const {
1745 return static_cast<FieldDecl*>(data[0]);
1746 }
1747 SourceLocation getLoc() const {
1748 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1749 }
1750};
Ted Kremenek28a71942010-11-13 00:36:47 +00001751class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1752 VisitorWorkList &WL;
1753 CXCursor Parent;
1754public:
1755 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1756 : WL(wl), Parent(parent) {}
1757
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001758 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001759 void VisitBlockExpr(BlockExpr *B);
Ted Kremenek28a71942010-11-13 00:36:47 +00001760 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenek083c7e22010-11-13 05:38:03 +00001761 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001762 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001763 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001764 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001765 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001766 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001767 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001768 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001769 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek55b933a2010-11-17 00:50:36 +00001770 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001771 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001772 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek035dc412010-11-13 00:36:50 +00001773 void VisitDeclStmt(DeclStmt *S);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001774 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001775 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001776 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1777 void VisitForStmt(ForStmt *FS);
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001778 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenek28a71942010-11-13 00:36:47 +00001779 void VisitIfStmt(IfStmt *If);
1780 void VisitInitListExpr(InitListExpr *IE);
1781 void VisitMemberExpr(MemberExpr *M);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001782 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001783 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001784 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1785 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00001786 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001787 void VisitStmt(Stmt *S);
1788 void VisitSwitchStmt(SwitchStmt *S);
1789 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek2939b6f2010-11-17 00:50:50 +00001790 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet6ad6f282010-12-07 00:08:36 +00001791 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
John Wiegley55262202011-04-25 06:54:41 +00001792 void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001793 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenek9d3bf792010-11-17 00:50:43 +00001794 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor94d96292011-01-19 20:34:17 +00001795 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregoree8aff02011-01-04 17:33:58 +00001796
Ted Kremenek28a71942010-11-13 00:36:47 +00001797private:
Ted Kremenekf64d8032010-11-18 00:02:32 +00001798 void AddDeclarationNameInfo(Stmt *S);
1799 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001800 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek60608ec2010-11-17 00:50:47 +00001801 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001802 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenek28a71942010-11-13 00:36:47 +00001803 void AddStmt(Stmt *S);
Ted Kremenek035dc412010-11-13 00:36:50 +00001804 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenek28a71942010-11-13 00:36:47 +00001805 void AddTypeLoc(TypeSourceInfo *TI);
1806 void EnqueueChildren(Stmt *S);
1807};
1808} // end anonyous namespace
1809
Ted Kremenekf64d8032010-11-18 00:02:32 +00001810void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1811 // 'S' should always be non-null, since it comes from the
1812 // statement we are visiting.
1813 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1814}
1815void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1816 SourceRange R) {
1817 if (N)
1818 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1819}
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001820
1821void
1822EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1823 if (Qualifier)
1824 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1825}
1826
Ted Kremenek28a71942010-11-13 00:36:47 +00001827void EnqueueVisitor::AddStmt(Stmt *S) {
1828 if (S)
1829 WL.push_back(StmtVisit(S, Parent));
1830}
Ted Kremenek035dc412010-11-13 00:36:50 +00001831void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001832 if (D)
Ted Kremenek035dc412010-11-13 00:36:50 +00001833 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenek28a71942010-11-13 00:36:47 +00001834}
Ted Kremenek60608ec2010-11-17 00:50:47 +00001835void EnqueueVisitor::
1836 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1837 if (A)
1838 WL.push_back(ExplicitTemplateArgsVisit(
1839 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1840}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001841void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1842 if (D)
1843 WL.push_back(MemberRefVisit(D, L, Parent));
1844}
Ted Kremenek28a71942010-11-13 00:36:47 +00001845void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1846 if (TI)
1847 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1848 }
1849void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremeneka6b70432010-11-12 21:34:09 +00001850 unsigned size = WL.size();
John McCall7502c1d2011-02-13 04:07:26 +00001851 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001852 AddStmt(*Child);
Ted Kremeneka6b70432010-11-12 21:34:09 +00001853 }
1854 if (size == WL.size())
1855 return;
1856 // Now reverse the entries we just added. This will match the DFS
1857 // ordering performed by the worklist.
1858 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1859 std::reverse(I, E);
1860}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001861void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1862 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1863}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001864void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1865 AddDecl(B->getBlockDecl());
1866}
Ted Kremenek28a71942010-11-13 00:36:47 +00001867void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1868 EnqueueChildren(E);
1869 AddTypeLoc(E->getTypeSourceInfo());
1870}
Ted Kremenek083c7e22010-11-13 05:38:03 +00001871void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1872 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1873 E = S->body_rend(); I != E; ++I) {
1874 AddStmt(*I);
1875 }
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001876}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001877void EnqueueVisitor::
1878VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1879 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1880 AddDeclarationNameInfo(E);
Douglas Gregor7c3179c2011-02-28 18:50:33 +00001881 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1882 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001883 if (!E->isImplicitAccess())
1884 AddStmt(E->getBase());
1885}
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001886void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1887 // Enqueue the initializer or constructor arguments.
1888 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1889 AddStmt(E->getConstructorArg(I-1));
1890 // Enqueue the array size, if any.
1891 AddStmt(E->getArraySize());
1892 // Enqueue the allocated type.
1893 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1894 // Enqueue the placement arguments.
1895 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1896 AddStmt(E->getPlacementArg(I-1));
1897}
Ted Kremenek28a71942010-11-13 00:36:47 +00001898void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenek8b8d8c92010-11-13 05:55:56 +00001899 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1900 AddStmt(CE->getArg(I-1));
Ted Kremenek28a71942010-11-13 00:36:47 +00001901 AddStmt(CE->getCallee());
1902 AddStmt(CE->getArg(0));
1903}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001904void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1905 // Visit the name of the type being destroyed.
1906 AddTypeLoc(E->getDestroyedTypeInfo());
1907 // Visit the scope type that looks disturbingly like the nested-name-specifier
1908 // but isn't.
1909 AddTypeLoc(E->getScopeTypeInfo());
1910 // Visit the nested-name-specifier.
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001911 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1912 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001913 // Visit base expression.
1914 AddStmt(E->getBase());
1915}
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001916void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1917 AddTypeLoc(E->getTypeSourceInfo());
1918}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001919void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1920 EnqueueChildren(E);
1921 AddTypeLoc(E->getTypeSourceInfo());
1922}
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001923void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1924 EnqueueChildren(E);
1925 if (E->isTypeOperand())
1926 AddTypeLoc(E->getTypeOperandSourceInfo());
1927}
Ted Kremenek55b933a2010-11-17 00:50:36 +00001928
1929void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1930 *E) {
1931 EnqueueChildren(E);
1932 AddTypeLoc(E->getTypeSourceInfo());
1933}
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001934void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1935 EnqueueChildren(E);
1936 if (E->isTypeOperand())
1937 AddTypeLoc(E->getTypeOperandSourceInfo());
1938}
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001939void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00001940 if (DR->hasExplicitTemplateArgs()) {
1941 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1942 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001943 WL.push_back(DeclRefExprParts(DR, Parent));
1944}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001945void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1946 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1947 AddDeclarationNameInfo(E);
Douglas Gregor00cf3cc2011-02-25 20:49:16 +00001948 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenekf64d8032010-11-18 00:02:32 +00001949}
Ted Kremenek035dc412010-11-13 00:36:50 +00001950void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1951 unsigned size = WL.size();
1952 bool isFirst = true;
1953 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1954 D != DEnd; ++D) {
1955 AddDecl(*D, isFirst);
1956 isFirst = false;
1957 }
1958 if (size == WL.size())
1959 return;
1960 // Now reverse the entries we just added. This will match the DFS
1961 // ordering performed by the worklist.
1962 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1963 std::reverse(I, E);
1964}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001965void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1966 AddStmt(E->getInit());
1967 typedef DesignatedInitExpr::Designator Designator;
1968 for (DesignatedInitExpr::reverse_designators_iterator
1969 D = E->designators_rbegin(), DEnd = E->designators_rend();
1970 D != DEnd; ++D) {
1971 if (D->isFieldDesignator()) {
1972 if (FieldDecl *Field = D->getField())
1973 AddMemberRef(Field, D->getFieldLoc());
1974 continue;
1975 }
1976 if (D->isArrayDesignator()) {
1977 AddStmt(E->getArrayIndex(*D));
1978 continue;
1979 }
1980 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1981 AddStmt(E->getArrayRangeEnd(*D));
1982 AddStmt(E->getArrayRangeStart(*D));
1983 }
1984}
Ted Kremenek28a71942010-11-13 00:36:47 +00001985void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1986 EnqueueChildren(E);
1987 AddTypeLoc(E->getTypeInfoAsWritten());
1988}
1989void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1990 AddStmt(FS->getBody());
1991 AddStmt(FS->getInc());
1992 AddStmt(FS->getCond());
1993 AddDecl(FS->getConditionVariable());
1994 AddStmt(FS->getInit());
1995}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001996void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1997 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1998}
Ted Kremenek28a71942010-11-13 00:36:47 +00001999void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
2000 AddStmt(If->getElse());
2001 AddStmt(If->getThen());
2002 AddStmt(If->getCond());
2003 AddDecl(If->getConditionVariable());
2004}
2005void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
2006 // We care about the syntactic form of the initializer list, only.
2007 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2008 IE = Syntactic;
2009 EnqueueChildren(IE);
2010}
2011void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor89629a72010-11-17 17:15:08 +00002012 WL.push_back(MemberExprParts(M, Parent));
2013
2014 // If the base of the member access expression is an implicit 'this', don't
2015 // visit it.
2016 // FIXME: If we ever want to show these implicit accesses, this will be
2017 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor75e85042011-03-02 21:06:53 +00002018 if (!M->isImplicitAccess())
2019 AddStmt(M->getBase());
Ted Kremenek28a71942010-11-13 00:36:47 +00002020}
Ted Kremenek73d15c42010-11-13 01:09:29 +00002021void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2022 AddTypeLoc(E->getEncodedTypeSourceInfo());
2023}
Ted Kremenek28a71942010-11-13 00:36:47 +00002024void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2025 EnqueueChildren(M);
2026 AddTypeLoc(M->getClassReceiverTypeInfo());
2027}
Ted Kremenekcdba6592010-11-18 00:42:18 +00002028void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2029 // Visit the components of the offsetof expression.
2030 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2031 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2032 const OffsetOfNode &Node = E->getComponent(I-1);
2033 switch (Node.getKind()) {
2034 case OffsetOfNode::Array:
2035 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2036 break;
2037 case OffsetOfNode::Field:
Abramo Bagnara06dec892011-03-12 09:45:03 +00002038 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenekcdba6592010-11-18 00:42:18 +00002039 break;
2040 case OffsetOfNode::Identifier:
2041 case OffsetOfNode::Base:
2042 continue;
2043 }
2044 }
2045 // Visit the type into which we're computing the offset.
2046 AddTypeLoc(E->getTypeSourceInfo());
2047}
Ted Kremenek28a71942010-11-13 00:36:47 +00002048void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00002049 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenek60458782010-11-12 21:34:16 +00002050 WL.push_back(OverloadExprParts(E, Parent));
2051}
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00002052void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2053 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00002054 EnqueueChildren(E);
2055 if (E->isArgumentType())
2056 AddTypeLoc(E->getArgumentTypeInfo());
2057}
Ted Kremenek28a71942010-11-13 00:36:47 +00002058void EnqueueVisitor::VisitStmt(Stmt *S) {
2059 EnqueueChildren(S);
2060}
2061void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2062 AddStmt(S->getBody());
2063 AddStmt(S->getCond());
2064 AddDecl(S->getConditionVariable());
2065}
Ted Kremenekfafa75a2010-11-17 00:50:39 +00002066
Ted Kremenek28a71942010-11-13 00:36:47 +00002067void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2068 AddStmt(W->getBody());
2069 AddStmt(W->getCond());
2070 AddDecl(W->getConditionVariable());
2071}
Ted Kremenek2939b6f2010-11-17 00:50:50 +00002072void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2073 AddTypeLoc(E->getQueriedTypeSourceInfo());
2074}
Francois Pichet6ad6f282010-12-07 00:08:36 +00002075
2076void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet6ad6f282010-12-07 00:08:36 +00002077 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichet0a03a3f2010-12-08 09:11:05 +00002078 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet6ad6f282010-12-07 00:08:36 +00002079}
2080
John Wiegley55262202011-04-25 06:54:41 +00002081void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2082 EnqueueChildren(E);
2083}
2084
Ted Kremenek28a71942010-11-13 00:36:47 +00002085void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2086 VisitOverloadExpr(U);
2087 if (!U->isImplicitAccess())
2088 AddStmt(U->getBase());
2089}
Ted Kremenek9d3bf792010-11-17 00:50:43 +00002090void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2091 AddStmt(E->getSubExpr());
2092 AddTypeLoc(E->getWrittenTypeInfo());
2093}
Douglas Gregor94d96292011-01-19 20:34:17 +00002094void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2095 WL.push_back(SizeOfPackExprParts(E, Parent));
2096}
Ted Kremenek60458782010-11-12 21:34:16 +00002097
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002098void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenek28a71942010-11-13 00:36:47 +00002099 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002100}
2101
2102bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2103 if (RegionOfInterest.isValid()) {
2104 SourceRange Range = getRawCursorExtent(C);
2105 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2106 return false;
2107 }
2108 return true;
2109}
2110
2111bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2112 while (!WL.empty()) {
2113 // Dequeue the worklist item.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002114 VisitorJob LI = WL.back();
2115 WL.pop_back();
2116
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002117 // Set the Parent field, then back to its old value once we're done.
2118 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2119
2120 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00002121 case VisitorJob::DeclVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002122 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenekf1107452010-11-12 18:26:56 +00002123 if (!D)
2124 continue;
2125
2126 // For now, perform default visitation for Decls.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002127 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenekf1107452010-11-12 18:26:56 +00002128 return true;
2129
2130 continue;
2131 }
Ted Kremenek60608ec2010-11-17 00:50:47 +00002132 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2133 const ExplicitTemplateArgumentList *ArgList =
2134 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2135 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2136 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2137 Arg != ArgEnd; ++Arg) {
2138 if (VisitTemplateArgumentLoc(*Arg))
2139 return true;
2140 }
2141 continue;
2142 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002143 case VisitorJob::TypeLocVisitKind: {
2144 // Perform default visitation for TypeLocs.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002145 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002146 return true;
2147 continue;
2148 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002149 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002150 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremeneke7455012011-02-23 04:54:51 +00002151 if (LabelStmt *stmt = LS->getStmt()) {
2152 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2153 TU))) {
2154 return true;
2155 }
2156 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002157 continue;
2158 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002159
Ted Kremenekf64d8032010-11-18 00:02:32 +00002160 case VisitorJob::NestedNameSpecifierVisitKind: {
2161 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2162 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2163 return true;
2164 continue;
2165 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002166
2167 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2168 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2169 if (VisitNestedNameSpecifierLoc(V->get()))
2170 return true;
2171 continue;
2172 }
2173
Ted Kremenekf64d8032010-11-18 00:02:32 +00002174 case VisitorJob::DeclarationNameInfoVisitKind: {
2175 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2176 ->get()))
2177 return true;
2178 continue;
2179 }
Ted Kremenekcdba6592010-11-18 00:42:18 +00002180 case VisitorJob::MemberRefVisitKind: {
2181 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2182 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2183 return true;
2184 continue;
2185 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002186 case VisitorJob::StmtVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002187 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002188 if (!S)
2189 continue;
2190
Ted Kremenekf1107452010-11-12 18:26:56 +00002191 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002192 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenekcdba6592010-11-18 00:42:18 +00002193 if (!IsInRegionOfInterest(Cursor))
2194 continue;
2195 switch (Visitor(Cursor, Parent, ClientData)) {
2196 case CXChildVisit_Break: return true;
2197 case CXChildVisit_Continue: break;
2198 case CXChildVisit_Recurse:
2199 EnqueueWorkList(WL, S);
Ted Kremenek82f3c502010-11-15 22:23:26 +00002200 break;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002201 }
Ted Kremenek82f3c502010-11-15 22:23:26 +00002202 continue;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002203 }
2204 case VisitorJob::MemberExprPartsKind: {
2205 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002206 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002207
2208 // Visit the nested-name-specifier
Douglas Gregor40d96a62011-02-28 21:54:11 +00002209 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2210 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002211 return true;
2212
2213 // Visit the declaration name.
2214 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2215 return true;
2216
2217 // Visit the explicitly-specified template arguments, if any.
2218 if (M->hasExplicitTemplateArgs()) {
2219 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2220 *ArgEnd = Arg + M->getNumTemplateArgs();
2221 Arg != ArgEnd; ++Arg) {
2222 if (VisitTemplateArgumentLoc(*Arg))
2223 return true;
2224 }
2225 }
2226 continue;
2227 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002228 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002229 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002230 // Visit nested-name-specifier, if present.
Douglas Gregor40d96a62011-02-28 21:54:11 +00002231 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2232 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002233 return true;
2234 // Visit declaration name.
2235 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2236 return true;
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002237 continue;
2238 }
Ted Kremenek60458782010-11-12 21:34:16 +00002239 case VisitorJob::OverloadExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002240 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenek60458782010-11-12 21:34:16 +00002241 // Visit the nested-name-specifier.
Douglas Gregor4c9be892011-02-28 20:01:57 +00002242 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2243 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek60458782010-11-12 21:34:16 +00002244 return true;
2245 // Visit the declaration name.
2246 if (VisitDeclarationNameInfo(O->getNameInfo()))
2247 return true;
2248 // Visit the overloaded declaration reference.
2249 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2250 return true;
Ted Kremenek60458782010-11-12 21:34:16 +00002251 continue;
2252 }
Douglas Gregor94d96292011-01-19 20:34:17 +00002253 case VisitorJob::SizeOfPackExprPartsKind: {
2254 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2255 NamedDecl *Pack = E->getPack();
2256 if (isa<TemplateTypeParmDecl>(Pack)) {
2257 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2258 E->getPackLoc(), TU)))
2259 return true;
2260
2261 continue;
2262 }
2263
2264 if (isa<TemplateTemplateParmDecl>(Pack)) {
2265 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2266 E->getPackLoc(), TU)))
2267 return true;
2268
2269 continue;
2270 }
2271
2272 // Non-type template parameter packs and function parameter packs are
2273 // treated like DeclRefExpr cursors.
2274 continue;
2275 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002276 }
2277 }
2278 return false;
2279}
2280
Ted Kremenekcdba6592010-11-18 00:42:18 +00002281bool CursorVisitor::Visit(Stmt *S) {
Ted Kremenekd1ded662010-11-15 23:31:32 +00002282 VisitorWorkList *WL = 0;
2283 if (!WorkListFreeList.empty()) {
2284 WL = WorkListFreeList.back();
2285 WL->clear();
2286 WorkListFreeList.pop_back();
2287 }
2288 else {
2289 WL = new VisitorWorkList();
2290 WorkListCache.push_back(WL);
2291 }
2292 EnqueueWorkList(*WL, S);
2293 bool result = RunVisitorWorkList(*WL);
2294 WorkListFreeList.push_back(WL);
2295 return result;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002296}
2297
2298//===----------------------------------------------------------------------===//
2299// Misc. API hooks.
2300//===----------------------------------------------------------------------===//
2301
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002302static llvm::sys::Mutex EnableMultithreadingMutex;
2303static bool EnabledMultithreading;
2304
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002305extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002306CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2307 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002308 // Disable pretty stack trace functionality, which will otherwise be a very
2309 // poor citizen of the world and set up all sorts of signal handlers.
2310 llvm::DisablePrettyStackTrace = true;
2311
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002312 // We use crash recovery to make some of our APIs more reliable, implicitly
2313 // enable it.
2314 llvm::CrashRecoveryContext::Enable();
2315
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002316 // Enable support for multithreading in LLVM.
2317 {
2318 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2319 if (!EnabledMultithreading) {
2320 llvm::llvm_start_multithreaded();
2321 EnabledMultithreading = true;
2322 }
2323 }
2324
Douglas Gregora030b7c2010-01-22 20:35:53 +00002325 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002326 if (excludeDeclarationsFromPCH)
2327 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002328 if (displayDiagnostics)
2329 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002330 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002331}
2332
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002333void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002334 if (CIdx)
2335 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002336}
2337
Ted Kremenekd2427dd2011-03-18 23:05:39 +00002338void clang_toggleCrashRecovery(unsigned isEnabled) {
2339 if (isEnabled)
2340 llvm::CrashRecoveryContext::Enable();
2341 else
2342 llvm::CrashRecoveryContext::Disable();
2343}
2344
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002345CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002346 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002347 if (!CIdx)
2348 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002349
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002350 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002351 FileSystemOptions FileSystemOpts;
2352 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002353
Douglas Gregor28019772010-04-05 23:52:57 +00002354 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremeneka60ed472010-11-16 08:15:36 +00002355 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002356 CXXIdx->getOnlyLocalDecls(),
2357 0, 0, true);
Ted Kremeneka60ed472010-11-16 08:15:36 +00002358 return MakeCXTranslationUnit(TU);
Steve Naroff600866c2009-08-27 19:51:58 +00002359}
2360
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002361unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002362 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002363 CXTranslationUnit_CacheCompletionResults |
2364 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002365}
2366
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002367CXTranslationUnit
2368clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2369 const char *source_filename,
2370 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002371 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002372 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002373 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor5a430212010-07-21 18:52:53 +00002374 return clang_parseTranslationUnit(CIdx, source_filename,
2375 command_line_args, num_command_line_args,
2376 unsaved_files, num_unsaved_files,
2377 CXTranslationUnit_DetailedPreprocessingRecord);
2378}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002379
2380struct ParseTranslationUnitInfo {
2381 CXIndex CIdx;
2382 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002383 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002384 int num_command_line_args;
2385 struct CXUnsavedFile *unsaved_files;
2386 unsigned num_unsaved_files;
2387 unsigned options;
2388 CXTranslationUnit result;
2389};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002390static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002391 ParseTranslationUnitInfo *PTUI =
2392 static_cast<ParseTranslationUnitInfo*>(UserData);
2393 CXIndex CIdx = PTUI->CIdx;
2394 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002395 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002396 int num_command_line_args = PTUI->num_command_line_args;
2397 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2398 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2399 unsigned options = PTUI->options;
2400 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002401
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002402 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002403 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002404
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002405 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2406
Douglas Gregor44c181a2010-07-23 00:33:23 +00002407 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002408 bool CompleteTranslationUnit
2409 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002410 bool CacheCodeCompetionResults
2411 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002412 bool CXXPrecompilePreamble
2413 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2414 bool CXXChainedPCH
2415 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002416
Douglas Gregor5352ac02010-01-28 00:27:43 +00002417 // Configure the diagnostics.
2418 DiagnosticOptions DiagOpts;
Ted Kremenek25a11e12011-03-22 01:15:24 +00002419 llvm::IntrusiveRefCntPtr<Diagnostic>
2420 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2421 command_line_args));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002422
Ted Kremenek25a11e12011-03-22 01:15:24 +00002423 // Recover resources if we crash before exiting this function.
2424 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2425 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2426 DiagCleanup(Diags.getPtr());
2427
2428 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2429 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2430
2431 // Recover resources if we crash before exiting this function.
2432 llvm::CrashRecoveryContextCleanupRegistrar<
2433 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2434
Douglas Gregor4db64a42010-01-23 00:14:00 +00002435 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002436 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002437 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002438 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002439 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2440 Buffer));
Douglas Gregor4db64a42010-01-23 00:14:00 +00002441 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002442
Ted Kremenek25a11e12011-03-22 01:15:24 +00002443 llvm::OwningPtr<std::vector<const char *> >
2444 Args(new std::vector<const char*>());
2445
2446 // Recover resources if we crash before exiting this method.
2447 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2448 ArgsCleanup(Args.get());
2449
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002450 // Since the Clang C library is primarily used by batch tools dealing with
2451 // (often very broken) source code, where spell-checking can have a
2452 // significant negative impact on performance (particularly when
2453 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002454 // Only do this if we haven't found a spell-checking-related argument.
2455 bool FoundSpellCheckingArgument = false;
2456 for (int I = 0; I != num_command_line_args; ++I) {
2457 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2458 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2459 FoundSpellCheckingArgument = true;
2460 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002461 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002462 }
2463 if (!FoundSpellCheckingArgument)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002464 Args->push_back("-fno-spell-checking");
Douglas Gregorb10daed2010-10-11 16:52:23 +00002465
Ted Kremenek25a11e12011-03-22 01:15:24 +00002466 Args->insert(Args->end(), command_line_args,
2467 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002468
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002469 // The 'source_filename' argument is optional. If the caller does not
2470 // specify it then it is assumed that the source file is specified
2471 // in the actual argument list.
2472 // Put the source file after command_line_args otherwise if '-x' flag is
2473 // present it will be unused.
2474 if (source_filename)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002475 Args->push_back(source_filename);
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002476
Douglas Gregor44c181a2010-07-23 00:33:23 +00002477 // Do we need the detailed preprocessing record?
2478 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek25a11e12011-03-22 01:15:24 +00002479 Args->push_back("-Xclang");
2480 Args->push_back("-detailed-preprocessing-record");
Douglas Gregor44c181a2010-07-23 00:33:23 +00002481 }
2482
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002483 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002484 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek4ee99262011-03-22 20:16:19 +00002485 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2486 /* vector::data() not portable */,
2487 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002488 Diags,
2489 CXXIdx->getClangResourcesPath(),
2490 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002491 /*CaptureDiagnostics=*/true,
Ted Kremenek4ee99262011-03-22 20:16:19 +00002492 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek25a11e12011-03-22 01:15:24 +00002493 RemappedFiles->size(),
Argyrios Kyrtzidis299a4a92011-03-08 23:35:24 +00002494 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002495 PrecompilePreamble,
2496 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002497 CacheCodeCompetionResults,
2498 CXXPrecompilePreamble,
2499 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002500
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002501 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002502 // Make sure to check that 'Unit' is non-NULL.
2503 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2504 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2505 DEnd = Unit->stored_diag_end();
2506 D != DEnd; ++D) {
2507 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2508 CXString Msg = clang_formatDiagnostic(&Diag,
2509 clang_defaultDiagnosticDisplayOptions());
2510 fprintf(stderr, "%s\n", clang_getCString(Msg));
2511 clang_disposeString(Msg);
2512 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002513#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002514 // On Windows, force a flush, since there may be multiple copies of
2515 // stderr and stdout in the file system, all with different buffers
2516 // but writing to the same device.
2517 fflush(stderr);
2518#endif
2519 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002520 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002521
Ted Kremeneka60ed472010-11-16 08:15:36 +00002522 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002523}
2524CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2525 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002526 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002527 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002528 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002529 unsigned num_unsaved_files,
2530 unsigned options) {
2531 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002532 num_command_line_args, unsaved_files,
2533 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002534 llvm::CrashRecoveryContext CRC;
2535
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002536 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002537 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2538 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2539 fprintf(stderr, " 'command_line_args' : [");
2540 for (int i = 0; i != num_command_line_args; ++i) {
2541 if (i)
2542 fprintf(stderr, ", ");
2543 fprintf(stderr, "'%s'", command_line_args[i]);
2544 }
2545 fprintf(stderr, "],\n");
2546 fprintf(stderr, " 'unsaved_files' : [");
2547 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2548 if (i)
2549 fprintf(stderr, ", ");
2550 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2551 unsaved_files[i].Length);
2552 }
2553 fprintf(stderr, "],\n");
2554 fprintf(stderr, " 'options' : %d,\n", options);
2555 fprintf(stderr, "}\n");
2556
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002557 return 0;
2558 }
2559
2560 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002561}
2562
Douglas Gregor19998442010-08-13 15:35:05 +00002563unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2564 return CXSaveTranslationUnit_None;
2565}
2566
2567int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2568 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002569 if (!TU)
2570 return 1;
2571
Ted Kremeneka60ed472010-11-16 08:15:36 +00002572 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002573}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002574
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002575void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002576 if (CTUnit) {
2577 // If the translation unit has been marked as unsafe to free, just discard
2578 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002579 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002580 return;
2581
Ted Kremeneka60ed472010-11-16 08:15:36 +00002582 delete static_cast<ASTUnit *>(CTUnit->TUData);
2583 disposeCXStringPool(CTUnit->StringPool);
2584 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002585 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002586}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002587
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002588unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2589 return CXReparse_None;
2590}
2591
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002592struct ReparseTranslationUnitInfo {
2593 CXTranslationUnit TU;
2594 unsigned num_unsaved_files;
2595 struct CXUnsavedFile *unsaved_files;
2596 unsigned options;
2597 int result;
2598};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002599
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002600static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002601 ReparseTranslationUnitInfo *RTUI =
2602 static_cast<ReparseTranslationUnitInfo*>(UserData);
2603 CXTranslationUnit TU = RTUI->TU;
2604 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2605 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2606 unsigned options = RTUI->options;
2607 (void) options;
2608 RTUI->result = 1;
2609
Douglas Gregorabc563f2010-07-19 21:46:24 +00002610 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002611 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002612
Ted Kremeneka60ed472010-11-16 08:15:36 +00002613 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002614 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002615
Ted Kremenek25a11e12011-03-22 01:15:24 +00002616 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2617 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2618
2619 // Recover resources if we crash before exiting this function.
2620 llvm::CrashRecoveryContextCleanupRegistrar<
2621 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2622
Douglas Gregorabc563f2010-07-19 21:46:24 +00002623 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2624 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2625 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002626 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002627 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2628 Buffer));
Douglas Gregorabc563f2010-07-19 21:46:24 +00002629 }
2630
Ted Kremenek4ee99262011-03-22 20:16:19 +00002631 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2632 RemappedFiles->size()))
Douglas Gregor593b0c12010-09-23 18:47:53 +00002633 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002634}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002635
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002636int clang_reparseTranslationUnit(CXTranslationUnit TU,
2637 unsigned num_unsaved_files,
2638 struct CXUnsavedFile *unsaved_files,
2639 unsigned options) {
2640 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2641 options, 0 };
2642 llvm::CrashRecoveryContext CRC;
2643
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002644 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002645 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002646 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002647 return 1;
2648 }
2649
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002650
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002651 return RTUI.result;
2652}
2653
Douglas Gregordf95a132010-08-09 20:45:32 +00002654
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002655CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002656 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002657 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002658
Ted Kremeneka60ed472010-11-16 08:15:36 +00002659 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002660 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002661}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002662
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002663CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002664 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002665 return Result;
2666}
2667
Ted Kremenekfb480492010-01-13 21:46:36 +00002668} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002669
Ted Kremenekfb480492010-01-13 21:46:36 +00002670//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002671// CXSourceLocation and CXSourceRange Operations.
2672//===----------------------------------------------------------------------===//
2673
Douglas Gregorb9790342010-01-22 21:44:22 +00002674extern "C" {
2675CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002676 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002677 return Result;
2678}
2679
2680unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002681 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2682 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2683 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002684}
2685
2686CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2687 CXFile file,
2688 unsigned line,
2689 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002690 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002691 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002692
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002693 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002694 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002695 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002696 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002697 = CXXUnit->getSourceManager().getLocation(File, line, column);
2698 if (SLoc.isInvalid()) {
2699 if (Logging)
2700 llvm::errs() << "clang_getLocation(\"" << File->getName()
2701 << "\", " << line << ", " << column << ") = invalid\n";
2702 return clang_getNullLocation();
2703 }
2704
2705 if (Logging)
2706 llvm::errs() << "clang_getLocation(\"" << File->getName()
2707 << "\", " << line << ", " << column << ") = "
2708 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002709
2710 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2711}
2712
2713CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2714 CXFile file,
2715 unsigned offset) {
2716 if (!tu || !file)
2717 return clang_getNullLocation();
2718
Ted Kremeneka60ed472010-11-16 08:15:36 +00002719 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002720 SourceLocation Start
2721 = CXXUnit->getSourceManager().getLocation(
2722 static_cast<const FileEntry *>(file),
2723 1, 1);
2724 if (Start.isInvalid()) return clang_getNullLocation();
2725
2726 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2727
2728 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002729
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002730 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002731}
2732
Douglas Gregor5352ac02010-01-28 00:27:43 +00002733CXSourceRange clang_getNullRange() {
2734 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2735 return Result;
2736}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002737
Douglas Gregor5352ac02010-01-28 00:27:43 +00002738CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2739 if (begin.ptr_data[0] != end.ptr_data[0] ||
2740 begin.ptr_data[1] != end.ptr_data[1])
2741 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002742
2743 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002744 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002745 return Result;
2746}
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002747} // end: extern "C"
Douglas Gregorb9790342010-01-22 21:44:22 +00002748
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002749static void createNullLocation(CXFile *file, unsigned *line,
2750 unsigned *column, unsigned *offset) {
2751 if (file)
2752 *file = 0;
2753 if (line)
2754 *line = 0;
2755 if (column)
2756 *column = 0;
2757 if (offset)
2758 *offset = 0;
2759 return;
2760}
2761
2762extern "C" {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002763void clang_getInstantiationLocation(CXSourceLocation location,
2764 CXFile *file,
2765 unsigned *line,
2766 unsigned *column,
2767 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002768 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2769
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002770 if (!location.ptr_data[0] || Loc.isInvalid()) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002771 createNullLocation(file, line, column, offset);
Douglas Gregor46766dc2010-01-26 19:19:08 +00002772 return;
2773 }
2774
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002775 const SourceManager &SM =
2776 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002777 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002778
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002779 // Check that the FileID is invalid on the instantiation location.
2780 // This can manifest in invalid code.
2781 FileID fileID = SM.getFileID(InstLoc);
Douglas Gregore23ac652011-04-20 00:21:03 +00002782 bool Invalid = false;
2783 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
2784 if (!sloc.isFile() || Invalid) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002785 createNullLocation(file, line, column, offset);
2786 return;
2787 }
2788
Douglas Gregor1db19de2010-01-19 21:36:55 +00002789 if (file)
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002790 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002791 if (line)
2792 *line = SM.getInstantiationLineNumber(InstLoc);
2793 if (column)
2794 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002795 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002796 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002797}
2798
Douglas Gregora9b06d42010-11-09 06:24:54 +00002799void clang_getSpellingLocation(CXSourceLocation location,
2800 CXFile *file,
2801 unsigned *line,
2802 unsigned *column,
2803 unsigned *offset) {
2804 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2805
2806 if (!location.ptr_data[0] || Loc.isInvalid()) {
2807 if (file)
2808 *file = 0;
2809 if (line)
2810 *line = 0;
2811 if (column)
2812 *column = 0;
2813 if (offset)
2814 *offset = 0;
2815 return;
2816 }
2817
2818 const SourceManager &SM =
2819 *static_cast<const SourceManager*>(location.ptr_data[0]);
2820 SourceLocation SpellLoc = Loc;
2821 if (SpellLoc.isMacroID()) {
2822 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2823 if (SimpleSpellingLoc.isFileID() &&
2824 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2825 SpellLoc = SimpleSpellingLoc;
2826 else
2827 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2828 }
2829
2830 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2831 FileID FID = LocInfo.first;
2832 unsigned FileOffset = LocInfo.second;
2833
2834 if (file)
2835 *file = (void *)SM.getFileEntryForID(FID);
2836 if (line)
2837 *line = SM.getLineNumber(FID, FileOffset);
2838 if (column)
2839 *column = SM.getColumnNumber(FID, FileOffset);
2840 if (offset)
2841 *offset = FileOffset;
2842}
2843
Douglas Gregor1db19de2010-01-19 21:36:55 +00002844CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002845 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002846 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002847 return Result;
2848}
2849
2850CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002851 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002852 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002853 return Result;
2854}
2855
Douglas Gregorb9790342010-01-22 21:44:22 +00002856} // end: extern "C"
2857
Douglas Gregor1db19de2010-01-19 21:36:55 +00002858//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002859// CXFile Operations.
2860//===----------------------------------------------------------------------===//
2861
2862extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002863CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002864 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002865 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002866
Steve Naroff88145032009-10-27 14:35:18 +00002867 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002868 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002869}
2870
2871time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002872 if (!SFile)
2873 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002874
Steve Naroff88145032009-10-27 14:35:18 +00002875 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2876 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002877}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002878
Douglas Gregorb9790342010-01-22 21:44:22 +00002879CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2880 if (!tu)
2881 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002882
Ted Kremeneka60ed472010-11-16 08:15:36 +00002883 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002884
Douglas Gregorb9790342010-01-22 21:44:22 +00002885 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002886 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002887}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002888
Ted Kremenekfb480492010-01-13 21:46:36 +00002889} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002890
Ted Kremenekfb480492010-01-13 21:46:36 +00002891//===----------------------------------------------------------------------===//
2892// CXCursor Operations.
2893//===----------------------------------------------------------------------===//
2894
Ted Kremenekfb480492010-01-13 21:46:36 +00002895static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002896 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2897 return getDeclFromExpr(CE->getSubExpr());
2898
Ted Kremenekfb480492010-01-13 21:46:36 +00002899 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2900 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002901 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2902 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002903 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2904 return ME->getMemberDecl();
2905 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2906 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002907 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002908 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002909
Ted Kremenekfb480492010-01-13 21:46:36 +00002910 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2911 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002912 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2913 if (!CE->isElidable())
2914 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002915 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2916 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002917
Douglas Gregordb1314e2010-10-01 21:11:22 +00002918 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2919 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002920 if (SubstNonTypeTemplateParmPackExpr *NTTP
2921 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2922 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002923 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2924 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2925 isa<ParmVarDecl>(SizeOfPack->getPack()))
2926 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002927
Ted Kremenekfb480492010-01-13 21:46:36 +00002928 return 0;
2929}
2930
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002931static SourceLocation getLocationFromExpr(Expr *E) {
2932 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2933 return /*FIXME:*/Msg->getLeftLoc();
2934 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2935 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002936 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2937 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002938 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2939 return Member->getMemberLoc();
2940 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2941 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002942 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2943 return SizeOfPack->getPackLoc();
2944
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002945 return E->getLocStart();
2946}
2947
Ted Kremenekfb480492010-01-13 21:46:36 +00002948extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002949
2950unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002951 CXCursorVisitor visitor,
2952 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002953 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00002954 getCursorASTUnit(parent)->getMaxPCHLevel(),
2955 false);
Douglas Gregorb1373d02010-01-20 20:59:29 +00002956 return CursorVis.VisitChildren(parent);
2957}
2958
David Chisnall3387c652010-11-03 14:12:26 +00002959#ifndef __has_feature
2960#define __has_feature(x) 0
2961#endif
2962#if __has_feature(blocks)
2963typedef enum CXChildVisitResult
2964 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2965
2966static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2967 CXClientData client_data) {
2968 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2969 return block(cursor, parent);
2970}
2971#else
2972// If we are compiled with a compiler that doesn't have native blocks support,
2973// define and call the block manually, so the
2974typedef struct _CXChildVisitResult
2975{
2976 void *isa;
2977 int flags;
2978 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002979 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2980 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002981} *CXCursorVisitorBlock;
2982
2983static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2984 CXClientData client_data) {
2985 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2986 return block->invoke(block, cursor, parent);
2987}
2988#endif
2989
2990
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002991unsigned clang_visitChildrenWithBlock(CXCursor parent,
2992 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002993 return clang_visitChildren(parent, visitWithBlock, block);
2994}
2995
Douglas Gregor78205d42010-01-20 21:45:58 +00002996static CXString getDeclSpelling(Decl *D) {
2997 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00002998 if (!ND) {
2999 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3000 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3001 return createCXString(Property->getIdentifier()->getName());
3002
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003003 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00003004 }
3005
Douglas Gregor78205d42010-01-20 21:45:58 +00003006 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003007 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003008
Douglas Gregor78205d42010-01-20 21:45:58 +00003009 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
3010 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3011 // and returns different names. NamedDecl returns the class name and
3012 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003013 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003014
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003015 if (isa<UsingDirectiveDecl>(D))
3016 return createCXString("");
3017
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00003018 llvm::SmallString<1024> S;
3019 llvm::raw_svector_ostream os(S);
3020 ND->printName(os);
3021
3022 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00003023}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003024
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003025CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003026 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003027 return clang_getTranslationUnitSpelling(
3028 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003029
Steve Narofff334b4e2009-09-02 18:26:48 +00003030 if (clang_isReference(C.kind)) {
3031 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00003032 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00003033 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003034 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003035 }
3036 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00003037 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003038 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003039 }
3040 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00003041 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00003042 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003043 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003044 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00003045 case CXCursor_CXXBaseSpecifier: {
3046 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3047 return createCXString(B->getType().getAsString());
3048 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003049 case CXCursor_TypeRef: {
3050 TypeDecl *Type = getCursorTypeRef(C).first;
3051 assert(Type && "Missing type decl");
3052
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003053 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3054 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003055 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003056 case CXCursor_TemplateRef: {
3057 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00003058 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003059
3060 return createCXString(Template->getNameAsString());
3061 }
Douglas Gregor69319002010-08-31 23:48:11 +00003062
3063 case CXCursor_NamespaceRef: {
3064 NamedDecl *NS = getCursorNamespaceRef(C).first;
3065 assert(NS && "Missing namespace decl");
3066
3067 return createCXString(NS->getNameAsString());
3068 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003069
Douglas Gregora67e03f2010-09-09 21:42:20 +00003070 case CXCursor_MemberRef: {
3071 FieldDecl *Field = getCursorMemberRef(C).first;
3072 assert(Field && "Missing member decl");
3073
3074 return createCXString(Field->getNameAsString());
3075 }
3076
Douglas Gregor36897b02010-09-10 00:22:18 +00003077 case CXCursor_LabelRef: {
3078 LabelStmt *Label = getCursorLabelRef(C).first;
3079 assert(Label && "Missing label");
3080
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003081 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003082 }
3083
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003084 case CXCursor_OverloadedDeclRef: {
3085 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3086 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3087 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3088 return createCXString(ND->getNameAsString());
3089 return createCXString("");
3090 }
3091 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3092 return createCXString(E->getName().getAsString());
3093 OverloadedTemplateStorage *Ovl
3094 = Storage.get<OverloadedTemplateStorage*>();
3095 if (Ovl->size() == 0)
3096 return createCXString("");
3097 return createCXString((*Ovl->begin())->getNameAsString());
3098 }
3099
Daniel Dunbaracca7252009-11-30 20:42:49 +00003100 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003101 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003102 }
3103 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003104
3105 if (clang_isExpression(C.kind)) {
3106 Decl *D = getDeclFromExpr(getCursorExpr(C));
3107 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003108 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003109 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003110 }
3111
Douglas Gregor36897b02010-09-10 00:22:18 +00003112 if (clang_isStatement(C.kind)) {
3113 Stmt *S = getCursorStmt(C);
3114 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003115 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003116
3117 return createCXString("");
3118 }
3119
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003120 if (C.kind == CXCursor_MacroInstantiation)
3121 return createCXString(getCursorMacroInstantiation(C)->getName()
3122 ->getNameStart());
3123
Douglas Gregor572feb22010-03-18 18:04:21 +00003124 if (C.kind == CXCursor_MacroDefinition)
3125 return createCXString(getCursorMacroDefinition(C)->getName()
3126 ->getNameStart());
3127
Douglas Gregorecdcb882010-10-20 22:00:55 +00003128 if (C.kind == CXCursor_InclusionDirective)
3129 return createCXString(getCursorInclusionDirective(C)->getFileName());
3130
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003131 if (clang_isDeclaration(C.kind))
3132 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003133
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003134 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003135}
3136
Douglas Gregor358559d2010-10-02 22:49:11 +00003137CXString clang_getCursorDisplayName(CXCursor C) {
3138 if (!clang_isDeclaration(C.kind))
3139 return clang_getCursorSpelling(C);
3140
3141 Decl *D = getCursorDecl(C);
3142 if (!D)
3143 return createCXString("");
3144
3145 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3146 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3147 D = FunTmpl->getTemplatedDecl();
3148
3149 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3150 llvm::SmallString<64> Str;
3151 llvm::raw_svector_ostream OS(Str);
3152 OS << Function->getNameAsString();
3153 if (Function->getPrimaryTemplate())
3154 OS << "<>";
3155 OS << "(";
3156 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3157 if (I)
3158 OS << ", ";
3159 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3160 }
3161
3162 if (Function->isVariadic()) {
3163 if (Function->getNumParams())
3164 OS << ", ";
3165 OS << "...";
3166 }
3167 OS << ")";
3168 return createCXString(OS.str());
3169 }
3170
3171 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3172 llvm::SmallString<64> Str;
3173 llvm::raw_svector_ostream OS(Str);
3174 OS << ClassTemplate->getNameAsString();
3175 OS << "<";
3176 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3177 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3178 if (I)
3179 OS << ", ";
3180
3181 NamedDecl *Param = Params->getParam(I);
3182 if (Param->getIdentifier()) {
3183 OS << Param->getIdentifier()->getName();
3184 continue;
3185 }
3186
3187 // There is no parameter name, which makes this tricky. Try to come up
3188 // with something useful that isn't too long.
3189 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3190 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3191 else if (NonTypeTemplateParmDecl *NTTP
3192 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3193 OS << NTTP->getType().getAsString(Policy);
3194 else
3195 OS << "template<...> class";
3196 }
3197
3198 OS << ">";
3199 return createCXString(OS.str());
3200 }
3201
3202 if (ClassTemplateSpecializationDecl *ClassSpec
3203 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3204 // If the type was explicitly written, use that.
3205 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3206 return createCXString(TSInfo->getType().getAsString(Policy));
3207
3208 llvm::SmallString<64> Str;
3209 llvm::raw_svector_ostream OS(Str);
3210 OS << ClassSpec->getNameAsString();
3211 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003212 ClassSpec->getTemplateArgs().data(),
3213 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003214 Policy);
3215 return createCXString(OS.str());
3216 }
3217
3218 return clang_getCursorSpelling(C);
3219}
3220
Ted Kremeneke68fff62010-02-17 00:41:32 +00003221CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003222 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003223 case CXCursor_FunctionDecl:
3224 return createCXString("FunctionDecl");
3225 case CXCursor_TypedefDecl:
3226 return createCXString("TypedefDecl");
3227 case CXCursor_EnumDecl:
3228 return createCXString("EnumDecl");
3229 case CXCursor_EnumConstantDecl:
3230 return createCXString("EnumConstantDecl");
3231 case CXCursor_StructDecl:
3232 return createCXString("StructDecl");
3233 case CXCursor_UnionDecl:
3234 return createCXString("UnionDecl");
3235 case CXCursor_ClassDecl:
3236 return createCXString("ClassDecl");
3237 case CXCursor_FieldDecl:
3238 return createCXString("FieldDecl");
3239 case CXCursor_VarDecl:
3240 return createCXString("VarDecl");
3241 case CXCursor_ParmDecl:
3242 return createCXString("ParmDecl");
3243 case CXCursor_ObjCInterfaceDecl:
3244 return createCXString("ObjCInterfaceDecl");
3245 case CXCursor_ObjCCategoryDecl:
3246 return createCXString("ObjCCategoryDecl");
3247 case CXCursor_ObjCProtocolDecl:
3248 return createCXString("ObjCProtocolDecl");
3249 case CXCursor_ObjCPropertyDecl:
3250 return createCXString("ObjCPropertyDecl");
3251 case CXCursor_ObjCIvarDecl:
3252 return createCXString("ObjCIvarDecl");
3253 case CXCursor_ObjCInstanceMethodDecl:
3254 return createCXString("ObjCInstanceMethodDecl");
3255 case CXCursor_ObjCClassMethodDecl:
3256 return createCXString("ObjCClassMethodDecl");
3257 case CXCursor_ObjCImplementationDecl:
3258 return createCXString("ObjCImplementationDecl");
3259 case CXCursor_ObjCCategoryImplDecl:
3260 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003261 case CXCursor_CXXMethod:
3262 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003263 case CXCursor_UnexposedDecl:
3264 return createCXString("UnexposedDecl");
3265 case CXCursor_ObjCSuperClassRef:
3266 return createCXString("ObjCSuperClassRef");
3267 case CXCursor_ObjCProtocolRef:
3268 return createCXString("ObjCProtocolRef");
3269 case CXCursor_ObjCClassRef:
3270 return createCXString("ObjCClassRef");
3271 case CXCursor_TypeRef:
3272 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003273 case CXCursor_TemplateRef:
3274 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003275 case CXCursor_NamespaceRef:
3276 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003277 case CXCursor_MemberRef:
3278 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003279 case CXCursor_LabelRef:
3280 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003281 case CXCursor_OverloadedDeclRef:
3282 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003283 case CXCursor_UnexposedExpr:
3284 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003285 case CXCursor_BlockExpr:
3286 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003287 case CXCursor_DeclRefExpr:
3288 return createCXString("DeclRefExpr");
3289 case CXCursor_MemberRefExpr:
3290 return createCXString("MemberRefExpr");
3291 case CXCursor_CallExpr:
3292 return createCXString("CallExpr");
3293 case CXCursor_ObjCMessageExpr:
3294 return createCXString("ObjCMessageExpr");
3295 case CXCursor_UnexposedStmt:
3296 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003297 case CXCursor_LabelStmt:
3298 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003299 case CXCursor_InvalidFile:
3300 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003301 case CXCursor_InvalidCode:
3302 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003303 case CXCursor_NoDeclFound:
3304 return createCXString("NoDeclFound");
3305 case CXCursor_NotImplemented:
3306 return createCXString("NotImplemented");
3307 case CXCursor_TranslationUnit:
3308 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003309 case CXCursor_UnexposedAttr:
3310 return createCXString("UnexposedAttr");
3311 case CXCursor_IBActionAttr:
3312 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003313 case CXCursor_IBOutletAttr:
3314 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003315 case CXCursor_IBOutletCollectionAttr:
3316 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003317 case CXCursor_PreprocessingDirective:
3318 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003319 case CXCursor_MacroDefinition:
3320 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003321 case CXCursor_MacroInstantiation:
3322 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003323 case CXCursor_InclusionDirective:
3324 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003325 case CXCursor_Namespace:
3326 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003327 case CXCursor_LinkageSpec:
3328 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003329 case CXCursor_CXXBaseSpecifier:
3330 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003331 case CXCursor_Constructor:
3332 return createCXString("CXXConstructor");
3333 case CXCursor_Destructor:
3334 return createCXString("CXXDestructor");
3335 case CXCursor_ConversionFunction:
3336 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003337 case CXCursor_TemplateTypeParameter:
3338 return createCXString("TemplateTypeParameter");
3339 case CXCursor_NonTypeTemplateParameter:
3340 return createCXString("NonTypeTemplateParameter");
3341 case CXCursor_TemplateTemplateParameter:
3342 return createCXString("TemplateTemplateParameter");
3343 case CXCursor_FunctionTemplate:
3344 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003345 case CXCursor_ClassTemplate:
3346 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003347 case CXCursor_ClassTemplatePartialSpecialization:
3348 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003349 case CXCursor_NamespaceAlias:
3350 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003351 case CXCursor_UsingDirective:
3352 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003353 case CXCursor_UsingDeclaration:
3354 return createCXString("UsingDeclaration");
Richard Smith162e1c12011-04-15 14:24:37 +00003355 case CXCursor_TypeAliasDecl:
3356 return createCXString("TypeAliasDecl");
Steve Naroff89922f82009-08-31 00:59:03 +00003357 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003358
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003359 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003360 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003361}
Steve Naroff89922f82009-08-31 00:59:03 +00003362
Ted Kremeneke68fff62010-02-17 00:41:32 +00003363enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3364 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003365 CXClientData client_data) {
3366 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003367
3368 // If our current best cursor is the construction of a temporary object,
3369 // don't replace that cursor with a type reference, because we want
3370 // clang_getCursor() to point at the constructor.
3371 if (clang_isExpression(BestCursor->kind) &&
3372 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3373 cursor.kind == CXCursor_TypeRef)
3374 return CXChildVisit_Recurse;
3375
Douglas Gregor85fe1562010-12-10 07:23:11 +00003376 // Don't override a preprocessing cursor with another preprocessing
3377 // cursor; we want the outermost preprocessing cursor.
3378 if (clang_isPreprocessing(cursor.kind) &&
3379 clang_isPreprocessing(BestCursor->kind))
3380 return CXChildVisit_Recurse;
3381
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003382 *BestCursor = cursor;
3383 return CXChildVisit_Recurse;
3384}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003385
Douglas Gregorb9790342010-01-22 21:44:22 +00003386CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3387 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003388 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003389
Ted Kremeneka60ed472010-11-16 08:15:36 +00003390 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003391 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3392
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003393 // Translate the given source location to make it point at the beginning of
3394 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003395 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003396
3397 // Guard against an invalid SourceLocation, or we may assert in one
3398 // of the following calls.
3399 if (SLoc.isInvalid())
3400 return clang_getNullCursor();
3401
Douglas Gregor40749ee2010-11-03 00:35:38 +00003402 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003403 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3404 CXXUnit->getASTContext().getLangOptions());
3405
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003406 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3407 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003408 // FIXME: Would be great to have a "hint" cursor, then walk from that
3409 // hint cursor upward until we find a cursor whose source range encloses
3410 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003411 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3412 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00003413 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003414 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003415 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003416
3417 if (Logging) {
3418 CXFile SearchFile;
3419 unsigned SearchLine, SearchColumn;
3420 CXFile ResultFile;
3421 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003422 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3423 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003424 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3425
3426 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3427 0);
3428 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3429 &ResultColumn, 0);
3430 SearchFileName = clang_getFileName(SearchFile);
3431 ResultFileName = clang_getFileName(ResultFile);
3432 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003433 USR = clang_getCursorUSR(Result);
3434 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003435 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3436 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003437 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3438 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003439 clang_disposeString(SearchFileName);
3440 clang_disposeString(ResultFileName);
3441 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003442 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003443
3444 CXCursor Definition = clang_getCursorDefinition(Result);
3445 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3446 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3447 CXString DefinitionKindSpelling
3448 = clang_getCursorKindSpelling(Definition.kind);
3449 CXFile DefinitionFile;
3450 unsigned DefinitionLine, DefinitionColumn;
3451 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3452 &DefinitionLine, &DefinitionColumn, 0);
3453 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3454 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3455 clang_getCString(DefinitionKindSpelling),
3456 clang_getCString(DefinitionFileName),
3457 DefinitionLine, DefinitionColumn);
3458 clang_disposeString(DefinitionFileName);
3459 clang_disposeString(DefinitionKindSpelling);
3460 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003461 }
3462
Ted Kremeneke68fff62010-02-17 00:41:32 +00003463 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003464}
3465
Ted Kremenek73885552009-11-17 19:28:59 +00003466CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003467 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003468}
3469
3470unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003471 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003472}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003473
Douglas Gregor9ce55842010-11-20 00:09:34 +00003474unsigned clang_hashCursor(CXCursor C) {
3475 unsigned Index = 0;
3476 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3477 Index = 1;
3478
3479 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3480 std::make_pair(C.kind, C.data[Index]));
3481}
3482
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003483unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003484 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3485}
3486
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003487unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003488 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3489}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003490
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003491unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003492 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3493}
3494
Douglas Gregor97b98722010-01-19 23:20:36 +00003495unsigned clang_isExpression(enum CXCursorKind K) {
3496 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3497}
3498
3499unsigned clang_isStatement(enum CXCursorKind K) {
3500 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3501}
3502
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003503unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3504 return K == CXCursor_TranslationUnit;
3505}
3506
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003507unsigned clang_isPreprocessing(enum CXCursorKind K) {
3508 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3509}
3510
Ted Kremenekad6eff62010-03-08 21:17:29 +00003511unsigned clang_isUnexposed(enum CXCursorKind K) {
3512 switch (K) {
3513 case CXCursor_UnexposedDecl:
3514 case CXCursor_UnexposedExpr:
3515 case CXCursor_UnexposedStmt:
3516 case CXCursor_UnexposedAttr:
3517 return true;
3518 default:
3519 return false;
3520 }
3521}
3522
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003523CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003524 return C.kind;
3525}
3526
Douglas Gregor98258af2010-01-18 22:46:11 +00003527CXSourceLocation clang_getCursorLocation(CXCursor C) {
3528 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003529 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003530 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003531 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3532 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003533 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003534 }
3535
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003536 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003537 std::pair<ObjCProtocolDecl *, SourceLocation> P
3538 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003539 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003540 }
3541
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003542 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003543 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3544 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003545 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003546 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003547
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003548 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003549 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003550 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003551 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003552
3553 case CXCursor_TemplateRef: {
3554 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3555 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3556 }
3557
Douglas Gregor69319002010-08-31 23:48:11 +00003558 case CXCursor_NamespaceRef: {
3559 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3560 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3561 }
3562
Douglas Gregora67e03f2010-09-09 21:42:20 +00003563 case CXCursor_MemberRef: {
3564 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3565 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3566 }
3567
Ted Kremenek3064ef92010-08-27 21:34:58 +00003568 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003569 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3570 if (!BaseSpec)
3571 return clang_getNullLocation();
3572
3573 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3574 return cxloc::translateSourceLocation(getCursorContext(C),
3575 TSInfo->getTypeLoc().getBeginLoc());
3576
3577 return cxloc::translateSourceLocation(getCursorContext(C),
3578 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003579 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003580
Douglas Gregor36897b02010-09-10 00:22:18 +00003581 case CXCursor_LabelRef: {
3582 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3583 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3584 }
3585
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003586 case CXCursor_OverloadedDeclRef:
3587 return cxloc::translateSourceLocation(getCursorContext(C),
3588 getCursorOverloadedDeclRef(C).second);
3589
Douglas Gregorf46034a2010-01-18 23:41:10 +00003590 default:
3591 // FIXME: Need a way to enumerate all non-reference cases.
3592 llvm_unreachable("Missed a reference kind");
3593 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003594 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003595
3596 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003597 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003598 getLocationFromExpr(getCursorExpr(C)));
3599
Douglas Gregor36897b02010-09-10 00:22:18 +00003600 if (clang_isStatement(C.kind))
3601 return cxloc::translateSourceLocation(getCursorContext(C),
3602 getCursorStmt(C)->getLocStart());
3603
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003604 if (C.kind == CXCursor_PreprocessingDirective) {
3605 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3606 return cxloc::translateSourceLocation(getCursorContext(C), L);
3607 }
Douglas Gregor48072312010-03-18 15:23:44 +00003608
3609 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003610 SourceLocation L
3611 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003612 return cxloc::translateSourceLocation(getCursorContext(C), L);
3613 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003614
3615 if (C.kind == CXCursor_MacroDefinition) {
3616 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3617 return cxloc::translateSourceLocation(getCursorContext(C), L);
3618 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003619
3620 if (C.kind == CXCursor_InclusionDirective) {
3621 SourceLocation L
3622 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3623 return cxloc::translateSourceLocation(getCursorContext(C), L);
3624 }
3625
Ted Kremenek9a700d22010-05-12 06:16:13 +00003626 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003627 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003628
Douglas Gregorf46034a2010-01-18 23:41:10 +00003629 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003630 SourceLocation Loc = D->getLocation();
3631 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3632 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003633 // FIXME: Multiple variables declared in a single declaration
3634 // currently lack the information needed to correctly determine their
3635 // ranges when accounting for the type-specifier. We use context
3636 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3637 // and if so, whether it is the first decl.
3638 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3639 if (!cxcursor::isFirstInDeclGroup(C))
3640 Loc = VD->getLocation();
3641 }
3642
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003643 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003644}
Douglas Gregora7bde202010-01-19 00:34:46 +00003645
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003646} // end extern "C"
3647
3648static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003649 if (clang_isReference(C.kind)) {
3650 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003651 case CXCursor_ObjCSuperClassRef:
3652 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003653
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003654 case CXCursor_ObjCProtocolRef:
3655 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003656
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003657 case CXCursor_ObjCClassRef:
3658 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003659
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003660 case CXCursor_TypeRef:
3661 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003662
3663 case CXCursor_TemplateRef:
3664 return getCursorTemplateRef(C).second;
3665
Douglas Gregor69319002010-08-31 23:48:11 +00003666 case CXCursor_NamespaceRef:
3667 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003668
3669 case CXCursor_MemberRef:
3670 return getCursorMemberRef(C).second;
3671
Ted Kremenek3064ef92010-08-27 21:34:58 +00003672 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003673 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003674
Douglas Gregor36897b02010-09-10 00:22:18 +00003675 case CXCursor_LabelRef:
3676 return getCursorLabelRef(C).second;
3677
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003678 case CXCursor_OverloadedDeclRef:
3679 return getCursorOverloadedDeclRef(C).second;
3680
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003681 default:
3682 // FIXME: Need a way to enumerate all non-reference cases.
3683 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003684 }
3685 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003686
3687 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003688 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003689
3690 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003691 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003692
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003693 if (C.kind == CXCursor_PreprocessingDirective)
3694 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003695
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003696 if (C.kind == CXCursor_MacroInstantiation)
3697 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003698
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003699 if (C.kind == CXCursor_MacroDefinition)
3700 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003701
3702 if (C.kind == CXCursor_InclusionDirective)
3703 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3704
Ted Kremenek007a7c92010-11-01 23:26:51 +00003705 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3706 Decl *D = cxcursor::getCursorDecl(C);
3707 SourceRange R = D->getSourceRange();
3708 // FIXME: Multiple variables declared in a single declaration
3709 // currently lack the information needed to correctly determine their
3710 // ranges when accounting for the type-specifier. We use context
3711 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3712 // and if so, whether it is the first decl.
3713 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3714 if (!cxcursor::isFirstInDeclGroup(C))
3715 R.setBegin(VD->getLocation());
3716 }
3717 return R;
3718 }
Douglas Gregor66537982010-11-17 17:14:07 +00003719 return SourceRange();
3720}
3721
3722/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3723/// the decl-specifier-seq for declarations.
3724static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3725 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3726 Decl *D = cxcursor::getCursorDecl(C);
3727 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003728
Douglas Gregor2494dd02011-03-01 01:34:45 +00003729 // Adjust the start of the location for declarations preceded by
3730 // declaration specifiers.
3731 SourceLocation StartLoc;
3732 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3733 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3734 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3735 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3736 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3737 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3738 }
3739
3740 if (StartLoc.isValid() && R.getBegin().isValid() &&
3741 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3742 R.setBegin(StartLoc);
3743
3744 // FIXME: Multiple variables declared in a single declaration
3745 // currently lack the information needed to correctly determine their
3746 // ranges when accounting for the type-specifier. We use context
3747 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3748 // and if so, whether it is the first decl.
3749 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3750 if (!cxcursor::isFirstInDeclGroup(C))
3751 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003752 }
3753
3754 return R;
3755 }
3756
3757 return getRawCursorExtent(C);
3758}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003759
3760extern "C" {
3761
3762CXSourceRange clang_getCursorExtent(CXCursor C) {
3763 SourceRange R = getRawCursorExtent(C);
3764 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003765 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003766
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003767 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003768}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003769
3770CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003771 if (clang_isInvalid(C.kind))
3772 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003773
Ted Kremeneka60ed472010-11-16 08:15:36 +00003774 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003775 if (clang_isDeclaration(C.kind)) {
3776 Decl *D = getCursorDecl(C);
3777 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003778 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003779 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003780 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003781 if (ObjCForwardProtocolDecl *Protocols
3782 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003783 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003784 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3785 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3786 return MakeCXCursor(Property, tu);
3787
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003788 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003789 }
3790
Douglas Gregor97b98722010-01-19 23:20:36 +00003791 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003792 Expr *E = getCursorExpr(C);
3793 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003794 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003795 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003796
3797 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003798 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003799
Douglas Gregor97b98722010-01-19 23:20:36 +00003800 return clang_getNullCursor();
3801 }
3802
Douglas Gregor36897b02010-09-10 00:22:18 +00003803 if (clang_isStatement(C.kind)) {
3804 Stmt *S = getCursorStmt(C);
3805 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek37c2e962011-03-15 23:47:49 +00003806 if (LabelDecl *label = Goto->getLabel())
3807 if (LabelStmt *labelS = label->getStmt())
3808 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003809
3810 return clang_getNullCursor();
3811 }
3812
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003813 if (C.kind == CXCursor_MacroInstantiation) {
3814 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003815 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003816 }
3817
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003818 if (!clang_isReference(C.kind))
3819 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003820
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003821 switch (C.kind) {
3822 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003823 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003824
3825 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003826 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003827
3828 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003829 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003830
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003831 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003832 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003833
3834 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003835 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003836
Douglas Gregor69319002010-08-31 23:48:11 +00003837 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003838 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003839
Douglas Gregora67e03f2010-09-09 21:42:20 +00003840 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003841 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003842
Ted Kremenek3064ef92010-08-27 21:34:58 +00003843 case CXCursor_CXXBaseSpecifier: {
3844 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3845 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003846 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003847 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003848
Douglas Gregor36897b02010-09-10 00:22:18 +00003849 case CXCursor_LabelRef:
3850 // FIXME: We end up faking the "parent" declaration here because we
3851 // don't want to make CXCursor larger.
3852 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003853 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3854 .getTranslationUnitDecl(),
3855 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003856
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003857 case CXCursor_OverloadedDeclRef:
3858 return C;
3859
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003860 default:
3861 // We would prefer to enumerate all non-reference cursor kinds here.
3862 llvm_unreachable("Unhandled reference cursor kind");
3863 break;
3864 }
3865 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003866
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003867 return clang_getNullCursor();
3868}
3869
Douglas Gregorb6998662010-01-19 19:34:47 +00003870CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003871 if (clang_isInvalid(C.kind))
3872 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003873
Ted Kremeneka60ed472010-11-16 08:15:36 +00003874 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003875
Douglas Gregorb6998662010-01-19 19:34:47 +00003876 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003877 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003878 C = clang_getCursorReferenced(C);
3879 WasReference = true;
3880 }
3881
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003882 if (C.kind == CXCursor_MacroInstantiation)
3883 return clang_getCursorReferenced(C);
3884
Douglas Gregorb6998662010-01-19 19:34:47 +00003885 if (!clang_isDeclaration(C.kind))
3886 return clang_getNullCursor();
3887
3888 Decl *D = getCursorDecl(C);
3889 if (!D)
3890 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003891
Douglas Gregorb6998662010-01-19 19:34:47 +00003892 switch (D->getKind()) {
3893 // Declaration kinds that don't really separate the notions of
3894 // declaration and definition.
3895 case Decl::Namespace:
3896 case Decl::Typedef:
Richard Smith162e1c12011-04-15 14:24:37 +00003897 case Decl::TypeAlias:
Douglas Gregorb6998662010-01-19 19:34:47 +00003898 case Decl::TemplateTypeParm:
3899 case Decl::EnumConstant:
3900 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003901 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003902 case Decl::ObjCIvar:
3903 case Decl::ObjCAtDefsField:
3904 case Decl::ImplicitParam:
3905 case Decl::ParmVar:
3906 case Decl::NonTypeTemplateParm:
3907 case Decl::TemplateTemplateParm:
3908 case Decl::ObjCCategoryImpl:
3909 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003910 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003911 case Decl::LinkageSpec:
3912 case Decl::ObjCPropertyImpl:
3913 case Decl::FileScopeAsm:
3914 case Decl::StaticAssert:
3915 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003916 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003917 return C;
3918
3919 // Declaration kinds that don't make any sense here, but are
3920 // nonetheless harmless.
3921 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003922 break;
3923
3924 // Declaration kinds for which the definition is not resolvable.
3925 case Decl::UnresolvedUsingTypename:
3926 case Decl::UnresolvedUsingValue:
3927 break;
3928
3929 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003930 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003931 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003932
3933 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003934 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003935
3936 case Decl::Enum:
3937 case Decl::Record:
3938 case Decl::CXXRecord:
3939 case Decl::ClassTemplateSpecialization:
3940 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003941 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003942 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003943 return clang_getNullCursor();
3944
3945 case Decl::Function:
3946 case Decl::CXXMethod:
3947 case Decl::CXXConstructor:
3948 case Decl::CXXDestructor:
3949 case Decl::CXXConversion: {
3950 const FunctionDecl *Def = 0;
3951 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003952 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003953 return clang_getNullCursor();
3954 }
3955
3956 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003957 // Ask the variable if it has a definition.
3958 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003959 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003960 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003961 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003962
Douglas Gregorb6998662010-01-19 19:34:47 +00003963 case Decl::FunctionTemplate: {
3964 const FunctionDecl *Def = 0;
3965 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003966 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003967 return clang_getNullCursor();
3968 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003969
Douglas Gregorb6998662010-01-19 19:34:47 +00003970 case Decl::ClassTemplate: {
3971 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003972 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003973 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003974 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003975 return clang_getNullCursor();
3976 }
3977
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003978 case Decl::Using:
3979 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003980 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003981
3982 case Decl::UsingShadow:
3983 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003984 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003985 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003986
3987 case Decl::ObjCMethod: {
3988 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3989 if (Method->isThisDeclarationADefinition())
3990 return C;
3991
3992 // Dig out the method definition in the associated
3993 // @implementation, if we have it.
3994 // FIXME: The ASTs should make finding the definition easier.
3995 if (ObjCInterfaceDecl *Class
3996 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3997 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3998 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3999 Method->isInstanceMethod()))
4000 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004001 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004002
4003 return clang_getNullCursor();
4004 }
4005
4006 case Decl::ObjCCategory:
4007 if (ObjCCategoryImplDecl *Impl
4008 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004009 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004010 return clang_getNullCursor();
4011
4012 case Decl::ObjCProtocol:
4013 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
4014 return C;
4015 return clang_getNullCursor();
4016
4017 case Decl::ObjCInterface:
4018 // There are two notions of a "definition" for an Objective-C
4019 // class: the interface and its implementation. When we resolved a
4020 // reference to an Objective-C class, produce the @interface as
4021 // the definition; when we were provided with the interface,
4022 // produce the @implementation as the definition.
4023 if (WasReference) {
4024 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4025 return C;
4026 } else if (ObjCImplementationDecl *Impl
4027 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004028 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004029 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004030
Douglas Gregorb6998662010-01-19 19:34:47 +00004031 case Decl::ObjCProperty:
4032 // FIXME: We don't really know where to find the
4033 // ObjCPropertyImplDecls that implement this property.
4034 return clang_getNullCursor();
4035
4036 case Decl::ObjCCompatibleAlias:
4037 if (ObjCInterfaceDecl *Class
4038 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4039 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004040 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004041
Douglas Gregorb6998662010-01-19 19:34:47 +00004042 return clang_getNullCursor();
4043
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004044 case Decl::ObjCForwardProtocol:
4045 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004046 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004047
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004048 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004049 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004050 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004051
4052 case Decl::Friend:
4053 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004054 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004055 return clang_getNullCursor();
4056
4057 case Decl::FriendTemplate:
4058 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004059 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004060 return clang_getNullCursor();
4061 }
4062
4063 return clang_getNullCursor();
4064}
4065
4066unsigned clang_isCursorDefinition(CXCursor C) {
4067 if (!clang_isDeclaration(C.kind))
4068 return 0;
4069
4070 return clang_getCursorDefinition(C) == C;
4071}
4072
Douglas Gregor1a9d0502010-11-19 23:44:15 +00004073CXCursor clang_getCanonicalCursor(CXCursor C) {
4074 if (!clang_isDeclaration(C.kind))
4075 return C;
4076
4077 if (Decl *D = getCursorDecl(C))
4078 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4079
4080 return C;
4081}
4082
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004083unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004084 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004085 return 0;
4086
4087 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4088 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4089 return E->getNumDecls();
4090
4091 if (OverloadedTemplateStorage *S
4092 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4093 return S->size();
4094
4095 Decl *D = Storage.get<Decl*>();
4096 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00004097 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004098 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4099 return Classes->size();
4100 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4101 return Protocols->protocol_size();
4102
4103 return 0;
4104}
4105
4106CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004107 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004108 return clang_getNullCursor();
4109
4110 if (index >= clang_getNumOverloadedDecls(cursor))
4111 return clang_getNullCursor();
4112
Ted Kremeneka60ed472010-11-16 08:15:36 +00004113 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004114 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4115 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004116 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004117
4118 if (OverloadedTemplateStorage *S
4119 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004120 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004121
4122 Decl *D = Storage.get<Decl*>();
4123 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4124 // FIXME: This is, unfortunately, linear time.
4125 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4126 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004127 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004128 }
4129
4130 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004131 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004132
4133 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004134 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004135
4136 return clang_getNullCursor();
4137}
4138
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004139void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004140 const char **startBuf,
4141 const char **endBuf,
4142 unsigned *startLine,
4143 unsigned *startColumn,
4144 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004145 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004146 assert(getCursorDecl(C) && "CXCursor has null decl");
4147 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004148 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4149 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004150
Steve Naroff4ade6d62009-09-23 17:52:52 +00004151 SourceManager &SM = FD->getASTContext().getSourceManager();
4152 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4153 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4154 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4155 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4156 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4157 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4158}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004159
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004160void clang_enableStackTraces(void) {
4161 llvm::sys::PrintStackTraceOnErrorSignal();
4162}
4163
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004164void clang_executeOnThread(void (*fn)(void*), void *user_data,
4165 unsigned stack_size) {
4166 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4167}
4168
Ted Kremenekfb480492010-01-13 21:46:36 +00004169} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004170
Ted Kremenekfb480492010-01-13 21:46:36 +00004171//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004172// Token-based Operations.
4173//===----------------------------------------------------------------------===//
4174
4175/* CXToken layout:
4176 * int_data[0]: a CXTokenKind
4177 * int_data[1]: starting token location
4178 * int_data[2]: token length
4179 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004180 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004181 * otherwise unused.
4182 */
4183extern "C" {
4184
4185CXTokenKind clang_getTokenKind(CXToken CXTok) {
4186 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4187}
4188
4189CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4190 switch (clang_getTokenKind(CXTok)) {
4191 case CXToken_Identifier:
4192 case CXToken_Keyword:
4193 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004194 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4195 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004196
4197 case CXToken_Literal: {
4198 // We have stashed the starting pointer in the ptr_data field. Use it.
4199 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004200 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004201 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004202
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004203 case CXToken_Punctuation:
4204 case CXToken_Comment:
4205 break;
4206 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004207
4208 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004209 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004210 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004211 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004212 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004213
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004214 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4215 std::pair<FileID, unsigned> LocInfo
4216 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004217 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004218 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004219 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4220 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004221 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004222
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004223 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004224}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004225
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004226CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004227 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004228 if (!CXXUnit)
4229 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004230
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004231 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4232 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4233}
4234
4235CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004236 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004237 if (!CXXUnit)
4238 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004239
4240 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004241 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4242}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004243
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004244void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4245 CXToken **Tokens, unsigned *NumTokens) {
4246 if (Tokens)
4247 *Tokens = 0;
4248 if (NumTokens)
4249 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004250
Ted Kremeneka60ed472010-11-16 08:15:36 +00004251 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004252 if (!CXXUnit || !Tokens || !NumTokens)
4253 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004254
Douglas Gregorbdf60622010-03-05 21:16:25 +00004255 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4256
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004257 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004258 if (R.isInvalid())
4259 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004260
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004261 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4262 std::pair<FileID, unsigned> BeginLocInfo
4263 = SourceMgr.getDecomposedLoc(R.getBegin());
4264 std::pair<FileID, unsigned> EndLocInfo
4265 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004266
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004267 // Cannot tokenize across files.
4268 if (BeginLocInfo.first != EndLocInfo.first)
4269 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004270
4271 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004272 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004273 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004274 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004275 if (Invalid)
4276 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004277
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004278 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4279 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004280 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004281 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004282
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004283 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004284 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004285 llvm::SmallVector<CXToken, 32> CXTokens;
4286 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004287 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004288 do {
4289 // Lex the next token
4290 Lex.LexFromRawLexer(Tok);
4291 if (Tok.is(tok::eof))
4292 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004293
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004294 // Initialize the CXToken.
4295 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004296
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004297 // - Common fields
4298 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4299 CXTok.int_data[2] = Tok.getLength();
4300 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004301
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004302 // - Kind-specific fields
4303 if (Tok.isLiteral()) {
4304 CXTok.int_data[0] = CXToken_Literal;
4305 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004306 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004307 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004308 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004309 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004310
David Chisnall096428b2010-10-13 21:44:48 +00004311 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004312 CXTok.int_data[0] = CXToken_Keyword;
4313 }
4314 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004315 CXTok.int_data[0] = Tok.is(tok::identifier)
4316 ? CXToken_Identifier
4317 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004318 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004319 CXTok.ptr_data = II;
4320 } else if (Tok.is(tok::comment)) {
4321 CXTok.int_data[0] = CXToken_Comment;
4322 CXTok.ptr_data = 0;
4323 } else {
4324 CXTok.int_data[0] = CXToken_Punctuation;
4325 CXTok.ptr_data = 0;
4326 }
4327 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004328 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004329 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004330
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004331 if (CXTokens.empty())
4332 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004333
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004334 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4335 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4336 *NumTokens = CXTokens.size();
4337}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004338
Ted Kremenek6db61092010-05-05 00:55:15 +00004339void clang_disposeTokens(CXTranslationUnit TU,
4340 CXToken *Tokens, unsigned NumTokens) {
4341 free(Tokens);
4342}
4343
4344} // end: extern "C"
4345
4346//===----------------------------------------------------------------------===//
4347// Token annotation APIs.
4348//===----------------------------------------------------------------------===//
4349
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004350typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004351static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4352 CXCursor parent,
4353 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004354namespace {
4355class AnnotateTokensWorker {
4356 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004357 CXToken *Tokens;
4358 CXCursor *Cursors;
4359 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004360 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004361 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004362 CursorVisitor AnnotateVis;
4363 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004364 bool HasContextSensitiveKeywords;
4365
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004366 bool MoreTokens() const { return TokIdx < NumTokens; }
4367 unsigned NextToken() const { return TokIdx; }
4368 void AdvanceToken() { ++TokIdx; }
4369 SourceLocation GetTokenLoc(unsigned tokI) {
4370 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4371 }
4372
Ted Kremenek6db61092010-05-05 00:55:15 +00004373public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004374 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004375 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004376 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004377 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004378 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004379 AnnotateVis(tu,
4380 AnnotateTokensVisitor, this,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00004381 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004382 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4383 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004384
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004385 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004386 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004387 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004388 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004389 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004390 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004391
4392 /// \brief Determine whether the annotator saw any cursors that have
4393 /// context-sensitive keywords.
4394 bool hasContextSensitiveKeywords() const {
4395 return HasContextSensitiveKeywords;
4396 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004397};
4398}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004399
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004400void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4401 // Walk the AST within the region of interest, annotating tokens
4402 // along the way.
4403 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004404
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004405 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4406 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004407 if (Pos != Annotated.end() &&
4408 (clang_isInvalid(Cursors[I].kind) ||
4409 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004410 Cursors[I] = Pos->second;
4411 }
4412
4413 // Finish up annotating any tokens left.
4414 if (!MoreTokens())
4415 return;
4416
4417 const CXCursor &C = clang_getNullCursor();
4418 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4419 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4420 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004421 }
4422}
4423
Ted Kremenek6db61092010-05-05 00:55:15 +00004424enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004425AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004426 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004427 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004428 if (cursorRange.isInvalid())
4429 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004430
4431 if (!HasContextSensitiveKeywords) {
4432 // Objective-C properties can have context-sensitive keywords.
4433 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4434 if (ObjCPropertyDecl *Property
4435 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4436 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4437 }
4438 // Objective-C methods can have context-sensitive keywords.
4439 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4440 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4441 if (ObjCMethodDecl *Method
4442 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4443 if (Method->getObjCDeclQualifier())
4444 HasContextSensitiveKeywords = true;
4445 else {
4446 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4447 PEnd = Method->param_end();
4448 P != PEnd; ++P) {
4449 if ((*P)->getObjCDeclQualifier()) {
4450 HasContextSensitiveKeywords = true;
4451 break;
4452 }
4453 }
4454 }
4455 }
4456 }
4457 // C++ methods can have context-sensitive keywords.
4458 else if (cursor.kind == CXCursor_CXXMethod) {
4459 if (CXXMethodDecl *Method
4460 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4461 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4462 HasContextSensitiveKeywords = true;
4463 }
4464 }
4465 // C++ classes can have context-sensitive keywords.
4466 else if (cursor.kind == CXCursor_StructDecl ||
4467 cursor.kind == CXCursor_ClassDecl ||
4468 cursor.kind == CXCursor_ClassTemplate ||
4469 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4470 if (Decl *D = getCursorDecl(cursor))
4471 if (D->hasAttr<FinalAttr>())
4472 HasContextSensitiveKeywords = true;
4473 }
4474 }
4475
Douglas Gregor4419b672010-10-21 06:10:04 +00004476 if (clang_isPreprocessing(cursor.kind)) {
4477 // For macro instantiations, just note where the beginning of the macro
4478 // instantiation occurs.
4479 if (cursor.kind == CXCursor_MacroInstantiation) {
4480 Annotated[Loc.int_data] = cursor;
4481 return CXChildVisit_Recurse;
4482 }
4483
Douglas Gregor4419b672010-10-21 06:10:04 +00004484 // Items in the preprocessing record are kept separate from items in
4485 // declarations, so we keep a separate token index.
4486 unsigned SavedTokIdx = TokIdx;
4487 TokIdx = PreprocessingTokIdx;
4488
4489 // Skip tokens up until we catch up to the beginning of the preprocessing
4490 // entry.
4491 while (MoreTokens()) {
4492 const unsigned I = NextToken();
4493 SourceLocation TokLoc = GetTokenLoc(I);
4494 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4495 case RangeBefore:
4496 AdvanceToken();
4497 continue;
4498 case RangeAfter:
4499 case RangeOverlap:
4500 break;
4501 }
4502 break;
4503 }
4504
4505 // Look at all of the tokens within this range.
4506 while (MoreTokens()) {
4507 const unsigned I = NextToken();
4508 SourceLocation TokLoc = GetTokenLoc(I);
4509 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4510 case RangeBefore:
4511 assert(0 && "Infeasible");
4512 case RangeAfter:
4513 break;
4514 case RangeOverlap:
4515 Cursors[I] = cursor;
4516 AdvanceToken();
4517 continue;
4518 }
4519 break;
4520 }
4521
4522 // Save the preprocessing token index; restore the non-preprocessing
4523 // token index.
4524 PreprocessingTokIdx = TokIdx;
4525 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004526 return CXChildVisit_Recurse;
4527 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004528
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004529 if (cursorRange.isInvalid())
4530 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004531
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004532 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4533
Ted Kremeneka333c662010-05-12 05:29:33 +00004534 // Adjust the annotated range based specific declarations.
4535 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4536 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004537 Decl *D = cxcursor::getCursorDecl(cursor);
4538 // Don't visit synthesized ObjC methods, since they have no syntatic
4539 // representation in the source.
4540 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4541 if (MD->isSynthesized())
4542 return CXChildVisit_Continue;
4543 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004544
4545 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004546 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004547 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4548 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4549 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4550 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4551 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004552 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004553
4554 if (StartLoc.isValid() && L.isValid() &&
4555 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4556 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004557 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004558
Ted Kremenek3f404602010-08-14 01:14:06 +00004559 // If the location of the cursor occurs within a macro instantiation, record
4560 // the spelling location of the cursor in our annotation map. We can then
4561 // paper over the token labelings during a post-processing step to try and
4562 // get cursor mappings for tokens that are the *arguments* of a macro
4563 // instantiation.
4564 if (L.isMacroID()) {
4565 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4566 // Only invalidate the old annotation if it isn't part of a preprocessing
4567 // directive. Here we assume that the default construction of CXCursor
4568 // results in CXCursor.kind being an initialized value (i.e., 0). If
4569 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004570
Ted Kremenek3f404602010-08-14 01:14:06 +00004571 CXCursor &oldC = Annotated[rawEncoding];
4572 if (!clang_isPreprocessing(oldC.kind))
4573 oldC = cursor;
4574 }
4575
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004576 const enum CXCursorKind K = clang_getCursorKind(parent);
4577 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004578 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4579 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004580
4581 while (MoreTokens()) {
4582 const unsigned I = NextToken();
4583 SourceLocation TokLoc = GetTokenLoc(I);
4584 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4585 case RangeBefore:
4586 Cursors[I] = updateC;
4587 AdvanceToken();
4588 continue;
4589 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004590 case RangeOverlap:
4591 break;
4592 }
4593 break;
4594 }
4595
4596 // Visit children to get their cursor information.
4597 const unsigned BeforeChildren = NextToken();
4598 VisitChildren(cursor);
4599 const unsigned AfterChildren = NextToken();
4600
4601 // Adjust 'Last' to the last token within the extent of the cursor.
4602 while (MoreTokens()) {
4603 const unsigned I = NextToken();
4604 SourceLocation TokLoc = GetTokenLoc(I);
4605 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4606 case RangeBefore:
4607 assert(0 && "Infeasible");
4608 case RangeAfter:
4609 break;
4610 case RangeOverlap:
4611 Cursors[I] = updateC;
4612 AdvanceToken();
4613 continue;
4614 }
4615 break;
4616 }
4617 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004618
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004619 // Scan the tokens that are at the beginning of the cursor, but are not
4620 // capture by the child cursors.
4621
4622 // For AST elements within macros, rely on a post-annotate pass to
4623 // to correctly annotate the tokens with cursors. Otherwise we can
4624 // get confusing results of having tokens that map to cursors that really
4625 // are expanded by an instantiation.
4626 if (L.isMacroID())
4627 cursor = clang_getNullCursor();
4628
4629 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4630 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4631 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004632
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004633 Cursors[I] = cursor;
4634 }
4635 // Scan the tokens that are at the end of the cursor, but are not captured
4636 // but the child cursors.
4637 for (unsigned I = AfterChildren; I != Last; ++I)
4638 Cursors[I] = cursor;
4639
4640 TokIdx = Last;
4641 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004642}
4643
Ted Kremenek6db61092010-05-05 00:55:15 +00004644static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4645 CXCursor parent,
4646 CXClientData client_data) {
4647 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4648}
4649
Ted Kremenek6628a612011-03-18 22:51:30 +00004650namespace {
4651 struct clang_annotateTokens_Data {
4652 CXTranslationUnit TU;
4653 ASTUnit *CXXUnit;
4654 CXToken *Tokens;
4655 unsigned NumTokens;
4656 CXCursor *Cursors;
4657 };
4658}
4659
Ted Kremenekab979612010-11-11 08:05:23 +00004660// This gets run a separate thread to avoid stack blowout.
Ted Kremenek6628a612011-03-18 22:51:30 +00004661static void clang_annotateTokensImpl(void *UserData) {
4662 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4663 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4664 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4665 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4666 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4667
4668 // Determine the region of interest, which contains all of the tokens.
4669 SourceRange RegionOfInterest;
4670 RegionOfInterest.setBegin(
4671 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4672 RegionOfInterest.setEnd(
4673 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4674 Tokens[NumTokens-1])));
4675
4676 // A mapping from the source locations found when re-lexing or traversing the
4677 // region of interest to the corresponding cursors.
4678 AnnotateTokensData Annotated;
4679
4680 // Relex the tokens within the source range to look for preprocessing
4681 // directives.
4682 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4683 std::pair<FileID, unsigned> BeginLocInfo
4684 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4685 std::pair<FileID, unsigned> EndLocInfo
4686 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4687
4688 llvm::StringRef Buffer;
4689 bool Invalid = false;
4690 if (BeginLocInfo.first == EndLocInfo.first &&
4691 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4692 !Invalid) {
4693 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4694 CXXUnit->getASTContext().getLangOptions(),
4695 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4696 Buffer.end());
4697 Lex.SetCommentRetentionState(true);
4698
4699 // Lex tokens in raw mode until we hit the end of the range, to avoid
4700 // entering #includes or expanding macros.
4701 while (true) {
4702 Token Tok;
4703 Lex.LexFromRawLexer(Tok);
4704
4705 reprocess:
4706 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4707 // We have found a preprocessing directive. Gobble it up so that we
4708 // don't see it while preprocessing these tokens later, but keep track
4709 // of all of the token locations inside this preprocessing directive so
4710 // that we can annotate them appropriately.
4711 //
4712 // FIXME: Some simple tests here could identify macro definitions and
4713 // #undefs, to provide specific cursor kinds for those.
4714 llvm::SmallVector<SourceLocation, 32> Locations;
4715 do {
4716 Locations.push_back(Tok.getLocation());
4717 Lex.LexFromRawLexer(Tok);
4718 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4719
4720 using namespace cxcursor;
4721 CXCursor Cursor
4722 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4723 Locations.back()),
4724 TU);
4725 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4726 Annotated[Locations[I].getRawEncoding()] = Cursor;
4727 }
4728
4729 if (Tok.isAtStartOfLine())
4730 goto reprocess;
4731
4732 continue;
4733 }
4734
4735 if (Tok.is(tok::eof))
4736 break;
4737 }
4738 }
4739
4740 // Annotate all of the source locations in the region of interest that map to
4741 // a specific cursor.
4742 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4743 TU, RegionOfInterest);
4744
4745 // FIXME: We use a ridiculous stack size here because the data-recursion
4746 // algorithm uses a large stack frame than the non-data recursive version,
4747 // and AnnotationTokensWorker currently transforms the data-recursion
4748 // algorithm back into a traditional recursion by explicitly calling
4749 // VisitChildren(). We will need to remove this explicit recursive call.
4750 W.AnnotateTokens();
4751
4752 // If we ran into any entities that involve context-sensitive keywords,
4753 // take another pass through the tokens to mark them as such.
4754 if (W.hasContextSensitiveKeywords()) {
4755 for (unsigned I = 0; I != NumTokens; ++I) {
4756 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4757 continue;
4758
4759 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4760 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4761 if (ObjCPropertyDecl *Property
4762 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4763 if (Property->getPropertyAttributesAsWritten() != 0 &&
4764 llvm::StringSwitch<bool>(II->getName())
4765 .Case("readonly", true)
4766 .Case("assign", true)
4767 .Case("readwrite", true)
4768 .Case("retain", true)
4769 .Case("copy", true)
4770 .Case("nonatomic", true)
4771 .Case("atomic", true)
4772 .Case("getter", true)
4773 .Case("setter", true)
4774 .Default(false))
4775 Tokens[I].int_data[0] = CXToken_Keyword;
4776 }
4777 continue;
4778 }
4779
4780 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4781 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4782 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4783 if (llvm::StringSwitch<bool>(II->getName())
4784 .Case("in", true)
4785 .Case("out", true)
4786 .Case("inout", true)
4787 .Case("oneway", true)
4788 .Case("bycopy", true)
4789 .Case("byref", true)
4790 .Default(false))
4791 Tokens[I].int_data[0] = CXToken_Keyword;
4792 continue;
4793 }
4794
4795 if (Cursors[I].kind == CXCursor_CXXMethod) {
4796 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4797 if (CXXMethodDecl *Method
4798 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4799 if ((Method->hasAttr<FinalAttr>() ||
4800 Method->hasAttr<OverrideAttr>()) &&
4801 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4802 llvm::StringSwitch<bool>(II->getName())
4803 .Case("final", true)
4804 .Case("override", true)
4805 .Default(false))
4806 Tokens[I].int_data[0] = CXToken_Keyword;
4807 }
4808 continue;
4809 }
4810
4811 if (Cursors[I].kind == CXCursor_ClassDecl ||
4812 Cursors[I].kind == CXCursor_StructDecl ||
4813 Cursors[I].kind == CXCursor_ClassTemplate) {
4814 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4815 if (II->getName() == "final") {
4816 // We have to be careful with 'final', since it could be the name
4817 // of a member class rather than the context-sensitive keyword.
4818 // So, check whether the cursor associated with this
4819 Decl *D = getCursorDecl(Cursors[I]);
4820 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4821 if ((Record->hasAttr<FinalAttr>()) &&
4822 Record->getIdentifier() != II)
4823 Tokens[I].int_data[0] = CXToken_Keyword;
4824 } else if (ClassTemplateDecl *ClassTemplate
4825 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4826 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4827 if ((Record->hasAttr<FinalAttr>()) &&
4828 Record->getIdentifier() != II)
4829 Tokens[I].int_data[0] = CXToken_Keyword;
4830 }
4831 }
4832 continue;
4833 }
4834 }
4835 }
Ted Kremenekab979612010-11-11 08:05:23 +00004836}
4837
Ted Kremenek6db61092010-05-05 00:55:15 +00004838extern "C" {
4839
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004840void clang_annotateTokens(CXTranslationUnit TU,
4841 CXToken *Tokens, unsigned NumTokens,
4842 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004843
4844 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004845 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004846
Douglas Gregor4419b672010-10-21 06:10:04 +00004847 // Any token we don't specifically annotate will have a NULL cursor.
4848 CXCursor C = clang_getNullCursor();
4849 for (unsigned I = 0; I != NumTokens; ++I)
4850 Cursors[I] = C;
4851
Ted Kremeneka60ed472010-11-16 08:15:36 +00004852 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004853 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004854 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004855
Douglas Gregorbdf60622010-03-05 21:16:25 +00004856 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek6628a612011-03-18 22:51:30 +00004857
4858 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekab979612010-11-11 08:05:23 +00004859 llvm::CrashRecoveryContext CRC;
Ted Kremenek6628a612011-03-18 22:51:30 +00004860 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004861 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004862 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4863 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004864}
Ted Kremenek6628a612011-03-18 22:51:30 +00004865
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004866} // end: extern "C"
4867
4868//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004869// Operations for querying linkage of a cursor.
4870//===----------------------------------------------------------------------===//
4871
4872extern "C" {
4873CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004874 if (!clang_isDeclaration(cursor.kind))
4875 return CXLinkage_Invalid;
4876
Ted Kremenek16b42592010-03-03 06:36:57 +00004877 Decl *D = cxcursor::getCursorDecl(cursor);
4878 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4879 switch (ND->getLinkage()) {
4880 case NoLinkage: return CXLinkage_NoLinkage;
4881 case InternalLinkage: return CXLinkage_Internal;
4882 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4883 case ExternalLinkage: return CXLinkage_External;
4884 };
4885
4886 return CXLinkage_Invalid;
4887}
4888} // end: extern "C"
4889
4890//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004891// Operations for querying language of a cursor.
4892//===----------------------------------------------------------------------===//
4893
4894static CXLanguageKind getDeclLanguage(const Decl *D) {
4895 switch (D->getKind()) {
4896 default:
4897 break;
4898 case Decl::ImplicitParam:
4899 case Decl::ObjCAtDefsField:
4900 case Decl::ObjCCategory:
4901 case Decl::ObjCCategoryImpl:
4902 case Decl::ObjCClass:
4903 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004904 case Decl::ObjCForwardProtocol:
4905 case Decl::ObjCImplementation:
4906 case Decl::ObjCInterface:
4907 case Decl::ObjCIvar:
4908 case Decl::ObjCMethod:
4909 case Decl::ObjCProperty:
4910 case Decl::ObjCPropertyImpl:
4911 case Decl::ObjCProtocol:
4912 return CXLanguage_ObjC;
4913 case Decl::CXXConstructor:
4914 case Decl::CXXConversion:
4915 case Decl::CXXDestructor:
4916 case Decl::CXXMethod:
4917 case Decl::CXXRecord:
4918 case Decl::ClassTemplate:
4919 case Decl::ClassTemplatePartialSpecialization:
4920 case Decl::ClassTemplateSpecialization:
4921 case Decl::Friend:
4922 case Decl::FriendTemplate:
4923 case Decl::FunctionTemplate:
4924 case Decl::LinkageSpec:
4925 case Decl::Namespace:
4926 case Decl::NamespaceAlias:
4927 case Decl::NonTypeTemplateParm:
4928 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004929 case Decl::TemplateTemplateParm:
4930 case Decl::TemplateTypeParm:
4931 case Decl::UnresolvedUsingTypename:
4932 case Decl::UnresolvedUsingValue:
4933 case Decl::Using:
4934 case Decl::UsingDirective:
4935 case Decl::UsingShadow:
4936 return CXLanguage_CPlusPlus;
4937 }
4938
4939 return CXLanguage_C;
4940}
4941
4942extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004943
4944enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4945 if (clang_isDeclaration(cursor.kind))
4946 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004947 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregor58ddb602010-08-23 23:00:57 +00004948 return CXAvailability_Available;
4949
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004950 switch (D->getAvailability()) {
4951 case AR_Available:
4952 case AR_NotYetIntroduced:
4953 return CXAvailability_Available;
4954
4955 case AR_Deprecated:
Douglas Gregor58ddb602010-08-23 23:00:57 +00004956 return CXAvailability_Deprecated;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004957
4958 case AR_Unavailable:
4959 return CXAvailability_NotAvailable;
4960 }
Douglas Gregor58ddb602010-08-23 23:00:57 +00004961 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004962
Douglas Gregor58ddb602010-08-23 23:00:57 +00004963 return CXAvailability_Available;
4964}
4965
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004966CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4967 if (clang_isDeclaration(cursor.kind))
4968 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4969
4970 return CXLanguage_Invalid;
4971}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004972
4973 /// \brief If the given cursor is the "templated" declaration
4974 /// descibing a class or function template, return the class or
4975 /// function template.
4976static Decl *maybeGetTemplateCursor(Decl *D) {
4977 if (!D)
4978 return 0;
4979
4980 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4981 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4982 return FunTmpl;
4983
4984 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4985 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4986 return ClassTmpl;
4987
4988 return D;
4989}
4990
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004991CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4992 if (clang_isDeclaration(cursor.kind)) {
4993 if (Decl *D = getCursorDecl(cursor)) {
4994 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004995 if (!DC)
4996 return clang_getNullCursor();
4997
4998 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4999 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005000 }
5001 }
5002
5003 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
5004 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00005005 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005006 }
5007
5008 return clang_getNullCursor();
5009}
5010
5011CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5012 if (clang_isDeclaration(cursor.kind)) {
5013 if (Decl *D = getCursorDecl(cursor)) {
5014 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00005015 if (!DC)
5016 return clang_getNullCursor();
5017
5018 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5019 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005020 }
5021 }
5022
5023 // FIXME: Note that we can't easily compute the lexical context of a
5024 // statement or expression, so we return nothing.
5025 return clang_getNullCursor();
5026}
5027
Douglas Gregor9f592342010-10-01 20:25:15 +00005028static void CollectOverriddenMethods(DeclContext *Ctx,
5029 ObjCMethodDecl *Method,
5030 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5031 if (!Ctx)
5032 return;
5033
5034 // If we have a class or category implementation, jump straight to the
5035 // interface.
5036 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5037 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5038
5039 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5040 if (!Container)
5041 return;
5042
5043 // Check whether we have a matching method at this level.
5044 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5045 Method->isInstanceMethod()))
5046 if (Method != Overridden) {
5047 // We found an override at this level; there is no need to look
5048 // into other protocols or categories.
5049 Methods.push_back(Overridden);
5050 return;
5051 }
5052
5053 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5054 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5055 PEnd = Protocol->protocol_end();
5056 P != PEnd; ++P)
5057 CollectOverriddenMethods(*P, Method, Methods);
5058 }
5059
5060 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5061 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5062 PEnd = Category->protocol_end();
5063 P != PEnd; ++P)
5064 CollectOverriddenMethods(*P, Method, Methods);
5065 }
5066
5067 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5068 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5069 PEnd = Interface->protocol_end();
5070 P != PEnd; ++P)
5071 CollectOverriddenMethods(*P, Method, Methods);
5072
5073 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5074 Category; Category = Category->getNextClassCategory())
5075 CollectOverriddenMethods(Category, Method, Methods);
5076
5077 // We only look into the superclass if we haven't found anything yet.
5078 if (Methods.empty())
5079 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5080 return CollectOverriddenMethods(Super, Method, Methods);
5081 }
5082}
5083
5084void clang_getOverriddenCursors(CXCursor cursor,
5085 CXCursor **overridden,
5086 unsigned *num_overridden) {
5087 if (overridden)
5088 *overridden = 0;
5089 if (num_overridden)
5090 *num_overridden = 0;
5091 if (!overridden || !num_overridden)
5092 return;
5093
5094 if (!clang_isDeclaration(cursor.kind))
5095 return;
5096
5097 Decl *D = getCursorDecl(cursor);
5098 if (!D)
5099 return;
5100
5101 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00005102 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00005103 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5104 *num_overridden = CXXMethod->size_overridden_methods();
5105 if (!*num_overridden)
5106 return;
5107
5108 *overridden = new CXCursor [*num_overridden];
5109 unsigned I = 0;
5110 for (CXXMethodDecl::method_iterator
5111 M = CXXMethod->begin_overridden_methods(),
5112 MEnd = CXXMethod->end_overridden_methods();
5113 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005114 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005115 return;
5116 }
5117
5118 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5119 if (!Method)
5120 return;
5121
5122 // Handle Objective-C methods.
5123 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5124 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5125
5126 if (Methods.empty())
5127 return;
5128
5129 *num_overridden = Methods.size();
5130 *overridden = new CXCursor [Methods.size()];
5131 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005132 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005133}
5134
5135void clang_disposeOverriddenCursors(CXCursor *overridden) {
5136 delete [] overridden;
5137}
5138
Douglas Gregorecdcb882010-10-20 22:00:55 +00005139CXFile clang_getIncludedFile(CXCursor cursor) {
5140 if (cursor.kind != CXCursor_InclusionDirective)
5141 return 0;
5142
5143 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5144 return (void *)ID->getFile();
5145}
5146
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005147} // end: extern "C"
5148
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005149
5150//===----------------------------------------------------------------------===//
5151// C++ AST instrospection.
5152//===----------------------------------------------------------------------===//
5153
5154extern "C" {
5155unsigned clang_CXXMethod_isStatic(CXCursor C) {
5156 if (!clang_isDeclaration(C.kind))
5157 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005158
5159 CXXMethodDecl *Method = 0;
5160 Decl *D = cxcursor::getCursorDecl(C);
5161 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5162 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5163 else
5164 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5165 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005166}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005167
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005168} // end: extern "C"
5169
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005170//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005171// Attribute introspection.
5172//===----------------------------------------------------------------------===//
5173
5174extern "C" {
5175CXType clang_getIBOutletCollectionType(CXCursor C) {
5176 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005177 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005178
5179 IBOutletCollectionAttr *A =
5180 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5181
Douglas Gregor841b2382011-03-06 18:55:32 +00005182 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005183}
5184} // end: extern "C"
5185
5186//===----------------------------------------------------------------------===//
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005187// Inspecting memory usage.
5188//===----------------------------------------------------------------------===//
5189
Ted Kremenekf7870022011-04-20 16:41:07 +00005190typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005191
Ted Kremenekf7870022011-04-20 16:41:07 +00005192static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
5193 enum CXTUResourceUsageKind k,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005194 double amount) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005195 CXTUResourceUsageEntry entry = { k, amount };
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005196 entries.push_back(entry);
5197}
5198
5199extern "C" {
5200
Ted Kremenekf7870022011-04-20 16:41:07 +00005201const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005202 const char *str = "";
5203 switch (kind) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005204 case CXTUResourceUsage_AST:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005205 str = "ASTContext: expressions, declarations, and types";
5206 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005207 case CXTUResourceUsage_Identifiers:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005208 str = "ASTContext: identifiers";
5209 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005210 case CXTUResourceUsage_Selectors:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005211 str = "ASTContext: selectors";
Ted Kremeneke294ab72011-04-19 04:36:17 +00005212 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005213 case CXTUResourceUsage_GlobalCompletionResults:
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005214 str = "Code completion: cached global results";
Ted Kremeneke294ab72011-04-19 04:36:17 +00005215 break;
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005216 }
5217 return str;
5218}
5219
Ted Kremenekf7870022011-04-20 16:41:07 +00005220CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005221 if (!TU) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005222 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005223 return usage;
5224 }
5225
5226 ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
5227 llvm::OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
5228 ASTContext &astContext = astUnit->getASTContext();
5229
5230 // How much memory is used by AST nodes and types?
Ted Kremenekf7870022011-04-20 16:41:07 +00005231 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005232 (unsigned long) astContext.getTotalAllocatedMemory());
5233
5234 // How much memory is used by identifiers?
Ted Kremenekf7870022011-04-20 16:41:07 +00005235 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005236 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
5237
5238 // How much memory is used for selectors?
Ted Kremenekf7870022011-04-20 16:41:07 +00005239 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005240 (unsigned long) astContext.Selectors.getTotalMemory());
5241
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005242 // How much memory is used for caching global code completion results?
5243 unsigned long completionBytes = 0;
5244 if (GlobalCodeCompletionAllocator *completionAllocator =
5245 astUnit->getCachedCompletionAllocator().getPtr()) {
5246 completionBytes = completionAllocator-> getTotalMemory();
5247 }
Ted Kremenekf7870022011-04-20 16:41:07 +00005248 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_GlobalCompletionResults,
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005249 completionBytes);
5250
5251
Ted Kremenekf7870022011-04-20 16:41:07 +00005252 CXTUResourceUsage usage = { (void*) entries.get(),
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005253 (unsigned) entries->size(),
5254 entries->size() ? &(*entries)[0] : 0 };
5255 entries.take();
5256 return usage;
5257}
5258
Ted Kremenekf7870022011-04-20 16:41:07 +00005259void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005260 if (usage.data)
5261 delete (MemUsageEntries*) usage.data;
5262}
5263
5264} // end extern "C"
5265
5266//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005267// Misc. utility functions.
5268//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005269
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005270/// Default to using an 8 MB stack size on "safety" threads.
5271static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005272
5273namespace clang {
5274
5275bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005276 void (*Fn)(void*), void *UserData,
5277 unsigned Size) {
5278 if (!Size)
5279 Size = GetSafetyThreadStackSize();
5280 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005281 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5282 return CRC.RunSafely(Fn, UserData);
5283}
5284
5285unsigned GetSafetyThreadStackSize() {
5286 return SafetyStackThreadSize;
5287}
5288
5289void SetSafetyThreadStackSize(unsigned Value) {
5290 SafetyStackThreadSize = Value;
5291}
5292
5293}
5294
Ted Kremenek04bb7162010-01-22 22:44:15 +00005295extern "C" {
5296
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005297CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005298 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005299}
5300
5301} // end: extern "C"
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005302