blob: 28f1506988e1498539dc7aaeecba8c2132d2cb02 [file] [log] [blame]
Ted Kremenekd2fa5662009-08-26 22:36:44 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00007//
Ted Kremenekd2fa5662009-08-26 22:36:44 +00008//===----------------------------------------------------------------------===//
9//
Ted Kremenekab188932010-01-05 19:32:54 +000010// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
Ted Kremenekd2fa5662009-08-26 22:36:44 +000012//
13//===----------------------------------------------------------------------===//
14
Ted Kremenekab188932010-01-05 19:32:54 +000015#include "CIndexer.h"
Ted Kremenek16c440a2010-01-15 20:35:54 +000016#include "CXCursor.h"
Ted Kremenek0a90d322010-11-17 23:24:11 +000017#include "CXTranslationUnit.h"
Ted Kremeneked122732010-11-16 01:56:27 +000018#include "CXString.h"
Ted Kremenek95f33552010-08-26 01:42:22 +000019#include "CXType.h"
Ted Kremeneka297de22010-01-25 22:34:44 +000020#include "CXSourceLocation.h"
Douglas Gregor5352ac02010-01-28 00:27:43 +000021#include "CIndexDiagnostic.h"
Ted Kremenekab188932010-01-05 19:32:54 +000022
Ted Kremenek04bb7162010-01-22 22:44:15 +000023#include "clang/Basic/Version.h"
Douglas Gregor936ea3b2010-01-28 00:56:43 +000024
Steve Naroff50398192009-08-28 15:28:48 +000025#include "clang/AST/DeclVisitor.h"
Steve Narofffb570422009-09-22 19:25:29 +000026#include "clang/AST/StmtVisitor.h"
Douglas Gregor7d0d40e2010-01-21 16:28:34 +000027#include "clang/AST/TypeLocVisitor.h"
Benjamin Kramerb846deb2010-04-12 19:45:50 +000028#include "clang/Basic/Diagnostic.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
Douglas Gregor936ea3b2010-01-28 00:56:43 +000031#include "clang/Frontend/FrontendDiagnostic.h"
Ted Kremenekd8210652010-01-06 23:43:31 +000032#include "clang/Lex/Lexer.h"
Benjamin Kramerb846deb2010-04-12 19:45:50 +000033#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregor33e9abd2010-01-22 19:49:59 +000034#include "clang/Lex/Preprocessor.h"
Douglas Gregora67e03f2010-09-09 21:42:20 +000035#include "llvm/ADT/STLExtras.h"
Ted Kremenekd8c370c2010-11-02 23:10:24 +000036#include "llvm/ADT/Optional.h"
Douglas Gregorf5251602011-03-08 17:10:18 +000037#include "llvm/ADT/StringSwitch.h"
Ted Kremenekd8c370c2010-11-02 23:10:24 +000038#include "clang/Analysis/Support/SaveAndRestore.h"
Daniel Dunbarc7df4f32010-08-18 18:43:14 +000039#include "llvm/Support/CrashRecoveryContext.h"
Daniel Dunbar48615ff2010-10-08 19:30:33 +000040#include "llvm/Support/PrettyStackTrace.h"
Douglas Gregor02465752009-10-16 21:24:31 +000041#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor358559d2010-10-02 22:49:11 +000042#include "llvm/Support/raw_ostream.h"
Douglas Gregor7a07fcb2010-08-09 21:00:09 +000043#include "llvm/Support/Timer.h"
Michael J. Spencer03013fa2010-11-29 18:12:39 +000044#include "llvm/Support/Mutex.h"
45#include "llvm/Support/Program.h"
46#include "llvm/Support/Signals.h"
47#include "llvm/Support/Threading.h"
Ted Kremenek37f1ea02010-11-15 23:11:54 +000048#include "llvm/Support/Compiler.h"
Ted Kremenekfc062212009-10-19 21:44:57 +000049
Steve Naroff50398192009-08-28 15:28:48 +000050using namespace clang;
Ted Kremenek16c440a2010-01-15 20:35:54 +000051using namespace clang::cxcursor;
Ted Kremenekee4db4f2010-02-17 00:41:08 +000052using namespace clang::cxstring;
Steve Naroff50398192009-08-28 15:28:48 +000053
Ted Kremeneka60ed472010-11-16 08:15:36 +000054static CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) {
55 if (!TU)
56 return 0;
57 CXTranslationUnit D = new CXTranslationUnitImpl();
58 D->TUData = TU;
59 D->StringPool = createCXStringPool();
60 return D;
61}
62
Douglas Gregor33e9abd2010-01-22 19:49:59 +000063/// \brief The result of comparing two source ranges.
64enum RangeComparisonResult {
65 /// \brief Either the ranges overlap or one of the ranges is invalid.
66 RangeOverlap,
Ted Kremenekf0e23e82010-02-17 00:41:40 +000067
Douglas Gregor33e9abd2010-01-22 19:49:59 +000068 /// \brief The first range ends before the second range starts.
69 RangeBefore,
Ted Kremenekf0e23e82010-02-17 00:41:40 +000070
Douglas Gregor33e9abd2010-01-22 19:49:59 +000071 /// \brief The first range starts after the second range ends.
72 RangeAfter
73};
74
Ted Kremenekf0e23e82010-02-17 00:41:40 +000075/// \brief Compare two source ranges to determine their relative position in
Douglas Gregor33e9abd2010-01-22 19:49:59 +000076/// the translation unit.
Ted Kremenekf0e23e82010-02-17 00:41:40 +000077static RangeComparisonResult RangeCompare(SourceManager &SM,
78 SourceRange R1,
Douglas Gregor33e9abd2010-01-22 19:49:59 +000079 SourceRange R2) {
80 assert(R1.isValid() && "First range is invalid?");
81 assert(R2.isValid() && "Second range is invalid?");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000082 if (R1.getEnd() != R2.getBegin() &&
Daniel Dunbard52864b2010-02-14 10:02:57 +000083 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
Douglas Gregor33e9abd2010-01-22 19:49:59 +000084 return RangeBefore;
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000085 if (R2.getEnd() != R1.getBegin() &&
Daniel Dunbard52864b2010-02-14 10:02:57 +000086 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
Douglas Gregor33e9abd2010-01-22 19:49:59 +000087 return RangeAfter;
88 return RangeOverlap;
89}
90
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000091/// \brief Determine if a source location falls within, before, or after a
92/// a given source range.
93static RangeComparisonResult LocationCompare(SourceManager &SM,
94 SourceLocation L, SourceRange R) {
95 assert(R.isValid() && "First range is invalid?");
96 assert(L.isValid() && "Second range is invalid?");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000097 if (L == R.getBegin() || L == R.getEnd())
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000098 return RangeOverlap;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000099 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
100 return RangeBefore;
101 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
102 return RangeAfter;
103 return RangeOverlap;
104}
105
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000106/// \brief Translate a Clang source range into a CIndex source range.
107///
108/// Clang internally represents ranges where the end location points to the
109/// start of the token at the end. However, for external clients it is more
110/// useful to have a CXSourceRange be a proper half-open interval. This routine
111/// does the appropriate translation.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000112CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000113 const LangOptions &LangOpts,
Chris Lattner0a76aae2010-06-18 22:45:06 +0000114 const CharSourceRange &R) {
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000115 // We want the last character in this location, so we will adjust the
Douglas Gregor6a5a23f2010-03-19 21:51:54 +0000116 // location accordingly.
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000117 SourceLocation EndLoc = R.getEnd();
Douglas Gregora9b06d42010-11-09 06:24:54 +0000118 if (EndLoc.isValid() && EndLoc.isMacroID())
Douglas Gregorffcd9852011-04-20 21:16:21 +0000119 EndLoc = SM.getInstantiationRange(EndLoc).second;
Chris Lattner0a76aae2010-06-18 22:45:06 +0000120 if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +0000121 unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000122 EndLoc = EndLoc.getFileLocWithOffset(Length);
123 }
124
125 CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
126 R.getBegin().getRawEncoding(),
127 EndLoc.getRawEncoding() };
128 return Result;
129}
Douglas Gregor1db19de2010-01-19 21:36:55 +0000130
Ted Kremenek8a8da7d2010-01-06 03:42:32 +0000131//===----------------------------------------------------------------------===//
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000132// Cursor visitor.
Ted Kremenek8a8da7d2010-01-06 03:42:32 +0000133//===----------------------------------------------------------------------===//
134
Steve Naroff89922f82009-08-31 00:59:03 +0000135namespace {
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000136
137class VisitorJob {
138public:
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000139 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
Ted Kremeneke4979cc2010-11-13 00:58:18 +0000140 TypeLocVisitKind, OverloadExprPartsKind,
Ted Kremenek60608ec2010-11-17 00:50:47 +0000141 DeclRefExprPartsKind, LabelRefVisitKind,
Ted Kremenekf64d8032010-11-18 00:02:32 +0000142 ExplicitTemplateArgsVisitKind,
143 NestedNameSpecifierVisitKind,
Douglas Gregorf3db29f2011-02-25 18:19:59 +0000144 NestedNameSpecifierLocVisitKind,
Ted Kremenekcdba6592010-11-18 00:42:18 +0000145 DeclarationNameInfoVisitKind,
Douglas Gregor94d96292011-01-19 20:34:17 +0000146 MemberRefVisitKind, SizeOfPackExprPartsKind };
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000147protected:
Ted Kremenekf64d8032010-11-18 00:02:32 +0000148 void *data[3];
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000149 CXCursor parent;
150 Kind K;
Ted Kremenekf64d8032010-11-18 00:02:32 +0000151 VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
152 : parent(C), K(k) {
153 data[0] = d1;
154 data[1] = d2;
155 data[2] = d3;
156 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000157public:
158 Kind getKind() const { return K; }
159 const CXCursor &getParent() const { return parent; }
160 static bool classof(VisitorJob *VJ) { return true; }
161};
162
163typedef llvm::SmallVector<VisitorJob, 10> VisitorWorkList;
164
Douglas Gregorb1373d02010-01-20 20:59:29 +0000165// Cursor visitor.
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000166class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
Ted Kremenekcdba6592010-11-18 00:42:18 +0000167 public TypeLocVisitor<CursorVisitor, bool>
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000168{
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000169 /// \brief The translation unit we are traversing.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000170 CXTranslationUnit TU;
171 ASTUnit *AU;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000172
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000173 /// \brief The parent cursor whose children we are traversing.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000174 CXCursor Parent;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000175
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000176 /// \brief The declaration that serves at the parent of any statement or
177 /// expression nodes.
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000178 Decl *StmtParent;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000179
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000180 /// \brief The visitor function.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000181 CXCursorVisitor Visitor;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000182
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000183 /// \brief The opaque client data, to be passed along to the visitor.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000184 CXClientData ClientData;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000185
Douglas Gregor7d1d49d2009-10-16 20:01:17 +0000186 // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
187 // to the visitor. Declarations with a PCH level greater than this value will
188 // be suppressed.
189 unsigned MaxPCHLevel;
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000190
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000191 /// \brief Whether we should visit the preprocessing record entries last,
192 /// after visiting other declarations.
193 bool VisitPreprocessorLast;
194
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000195 /// \brief When valid, a source range to which the cursor should restrict
196 /// its search.
197 SourceRange RegionOfInterest;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000198
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000199 // FIXME: Eventually remove. This part of a hack to support proper
200 // iteration over all Decls contained lexically within an ObjC container.
201 DeclContext::decl_iterator *DI_current;
202 DeclContext::decl_iterator DE_current;
203
Ted Kremenekd1ded662010-11-15 23:31:32 +0000204 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
205 llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
206 llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
207
Douglas Gregorb1373d02010-01-20 20:59:29 +0000208 using DeclVisitor<CursorVisitor, bool>::Visit;
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000209 using TypeLocVisitor<CursorVisitor, bool>::Visit;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000210
211 /// \brief Determine whether this particular source range comes before, comes
212 /// after, or overlaps the region of interest.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000213 ///
Daniel Dunbard52864b2010-02-14 10:02:57 +0000214 /// \param R a half-open source range retrieved from the abstract syntax tree.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000215 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
216
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000217 class SetParentRAII {
218 CXCursor &Parent;
219 Decl *&StmtParent;
220 CXCursor OldParent;
221
222 public:
223 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
224 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
225 {
226 Parent = NewParent;
227 if (clang_isDeclaration(Parent.kind))
228 StmtParent = getCursorDecl(Parent);
229 }
230
231 ~SetParentRAII() {
232 Parent = OldParent;
233 if (clang_isDeclaration(Parent.kind))
234 StmtParent = getCursorDecl(Parent);
235 }
236 };
237
Steve Naroff89922f82009-08-31 00:59:03 +0000238public:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000239 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
240 CXClientData ClientData,
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000241 unsigned MaxPCHLevel,
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000242 bool VisitPreprocessorLast,
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000243 SourceRange RegionOfInterest = SourceRange())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000244 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
245 Visitor(Visitor), ClientData(ClientData),
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000246 MaxPCHLevel(MaxPCHLevel), VisitPreprocessorLast(VisitPreprocessorLast),
247 RegionOfInterest(RegionOfInterest), DI_current(0)
Douglas Gregorb1373d02010-01-20 20:59:29 +0000248 {
249 Parent.kind = CXCursor_NoDeclFound;
250 Parent.data[0] = 0;
251 Parent.data[1] = 0;
252 Parent.data[2] = 0;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000253 StmtParent = 0;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000254 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000255
Ted Kremenekd1ded662010-11-15 23:31:32 +0000256 ~CursorVisitor() {
257 // Free the pre-allocated worklists for data-recursion.
258 for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
259 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
260 delete *I;
261 }
262 }
263
Ted Kremeneka60ed472010-11-16 08:15:36 +0000264 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
265 CXTranslationUnit getTU() const { return TU; }
Ted Kremenekab979612010-11-11 08:05:23 +0000266
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000267 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000268
269 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
270 getPreprocessedEntities();
271
Douglas Gregorb1373d02010-01-20 20:59:29 +0000272 bool VisitChildren(CXCursor Parent);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000273
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000274 // Declaration visitors
Richard Smith162e1c12011-04-15 14:24:37 +0000275 bool VisitTypeAliasDecl(TypeAliasDecl *D);
Ted Kremenek09dfa372010-02-18 05:46:33 +0000276 bool VisitAttributes(Decl *D);
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000277 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenek3064ef92010-08-27 21:34:58 +0000278 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000279 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000280 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000281 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
282 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000283 bool VisitTagDecl(TagDecl *D);
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000284 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregor74dbe642010-08-31 19:31:58 +0000285 bool VisitClassTemplatePartialSpecializationDecl(
286 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000287 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000288 bool VisitEnumConstantDecl(EnumConstantDecl *D);
289 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
290 bool VisitFunctionDecl(FunctionDecl *ND);
291 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000292 bool VisitVarDecl(VarDecl *);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000293 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000294 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor39d6f072010-08-31 19:02:00 +0000295 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000296 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000297 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
298 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
299 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
300 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek23173d72010-05-18 21:09:07 +0000301 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremenek79758f62010-02-18 22:36:18 +0000302 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
303 bool VisitObjCImplDecl(ObjCImplDecl *D);
304 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
305 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000306 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
307 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
308 bool VisitObjCClassDecl(ObjCClassDecl *D);
Douglas Gregora4ffd852010-11-17 01:03:52 +0000309 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
Ted Kremeneka0536d82010-05-07 01:04:29 +0000310 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenek8f06e0e2010-05-06 23:38:21 +0000311 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregor69319002010-08-31 23:48:11 +0000312 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000313 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregor7e242562010-09-01 19:52:22 +0000314 bool VisitUsingDecl(UsingDecl *D);
315 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
316 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000317
Douglas Gregor01829d32010-08-31 14:41:23 +0000318 // Name visitor
319 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000320 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregordc355712011-02-25 00:36:19 +0000321 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
Douglas Gregor01829d32010-08-31 14:41:23 +0000322
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000323 // Template visitors
324 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregor0b36e612010-08-31 20:37:03 +0000325 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000326 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
327
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000328 // Type visitors
Douglas Gregor01829d32010-08-31 14:41:23 +0000329 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000330 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000331 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000332 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
333 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000334 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000335 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCallc12c5bb2010-05-15 11:32:37 +0000336 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000337 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
Abramo Bagnara075f8f12010-12-10 16:29:40 +0000338 bool VisitParenTypeLoc(ParenTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000339 bool VisitPointerTypeLoc(PointerTypeLoc TL);
340 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
341 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
342 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
343 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor01829d32010-08-31 14:41:23 +0000344 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000345 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000346 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000347 // FIXME: Implement visitors here when the unimplemented TypeLocs get
348 // implemented
349 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
Douglas Gregor7536dd52010-12-20 02:24:11 +0000350 bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000351 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000352 bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
Douglas Gregor94fdffa2011-03-01 20:11:18 +0000353 bool VisitDependentTemplateSpecializationTypeLoc(
354 DependentTemplateSpecializationTypeLoc TL);
Douglas Gregor9e876872011-03-01 18:12:44 +0000355 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000356
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000357 // Data-recursive visitor functions.
358 bool IsInRegionOfInterest(CXCursor C);
359 bool RunVisitorWorkList(VisitorWorkList &WL);
360 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
Ted Kremenekcdba6592010-11-18 00:42:18 +0000361 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
Steve Naroff89922f82009-08-31 00:59:03 +0000362};
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000363
Ted Kremenekab188932010-01-05 19:32:54 +0000364} // end anonymous namespace
Benjamin Kramer5e4bc592009-10-18 16:11:04 +0000365
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000366static SourceRange getRawCursorExtent(CXCursor C);
Douglas Gregor66537982010-11-17 17:14:07 +0000367static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
368
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000369
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000370RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000371 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000372}
373
Douglas Gregorb1373d02010-01-20 20:59:29 +0000374/// \brief Visit the given cursor and, if requested by the visitor,
375/// its children.
376///
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000377/// \param Cursor the cursor to visit.
378///
379/// \param CheckRegionOfInterest if true, then the caller already checked that
380/// this cursor is within the region of interest.
381///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000382/// \returns true if the visitation should be aborted, false if it
383/// should continue.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000384bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregorb1373d02010-01-20 20:59:29 +0000385 if (clang_isInvalid(Cursor.kind))
386 return false;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000387
Douglas Gregorb1373d02010-01-20 20:59:29 +0000388 if (clang_isDeclaration(Cursor.kind)) {
389 Decl *D = getCursorDecl(Cursor);
390 assert(D && "Invalid declaration cursor");
391 if (D->getPCHLevel() > MaxPCHLevel)
392 return false;
393
394 if (D->isImplicit())
395 return false;
396 }
397
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000398 // If we have a range of interest, and this cursor doesn't intersect with it,
399 // we're done.
400 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000401 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbarf408f322010-02-14 08:32:05 +0000402 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000403 return false;
404 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000405
Douglas Gregorb1373d02010-01-20 20:59:29 +0000406 switch (Visitor(Cursor, Parent, ClientData)) {
407 case CXChildVisit_Break:
408 return true;
409
410 case CXChildVisit_Continue:
411 return false;
412
413 case CXChildVisit_Recurse:
414 return VisitChildren(Cursor);
415 }
416
Douglas Gregorfd643772010-01-25 16:45:46 +0000417 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000418}
419
Douglas Gregor788f5a12010-03-20 00:41:21 +0000420std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
421CursorVisitor::getPreprocessedEntities() {
422 PreprocessingRecord &PPRec
Ted Kremeneka60ed472010-11-16 08:15:36 +0000423 = *AU->getPreprocessor().getPreprocessingRecord();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000424
425 bool OnlyLocalDecls
Douglas Gregor32038bb2010-12-21 19:07:48 +0000426 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
427
428 if (OnlyLocalDecls && RegionOfInterest.isValid()) {
429 // If we would only look at local declarations but we have a region of
430 // interest, check whether that region of interest is in the main file.
431 // If not, we should traverse all declarations.
432 // FIXME: My kingdom for a proper binary search approach to finding
433 // cursors!
434 std::pair<FileID, unsigned> Location
435 = AU->getSourceManager().getDecomposedInstantiationLoc(
436 RegionOfInterest.getBegin());
437 if (Location.first != AU->getSourceManager().getMainFileID())
438 OnlyLocalDecls = false;
439 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000440
Douglas Gregor89d99802010-11-30 06:16:57 +0000441 PreprocessingRecord::iterator StartEntity, EndEntity;
442 if (OnlyLocalDecls) {
443 StartEntity = AU->pp_entity_begin();
444 EndEntity = AU->pp_entity_end();
445 } else {
446 StartEntity = PPRec.begin();
447 EndEntity = PPRec.end();
448 }
449
Douglas Gregor788f5a12010-03-20 00:41:21 +0000450 // There is no region of interest; we have to walk everything.
451 if (RegionOfInterest.isInvalid())
Douglas Gregor89d99802010-11-30 06:16:57 +0000452 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000453
454 // Find the file in which the region of interest lands.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000455 SourceManager &SM = AU->getSourceManager();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000456 std::pair<FileID, unsigned> Begin
457 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
458 std::pair<FileID, unsigned> End
459 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
460
461 // The region of interest spans files; we have to walk everything.
462 if (Begin.first != End.first)
Douglas Gregor89d99802010-11-30 06:16:57 +0000463 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000464
465 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
Ted Kremeneka60ed472010-11-16 08:15:36 +0000466 = AU->getPreprocessedEntitiesByFile();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000467 if (ByFileMap.empty()) {
468 // Build the mapping from files to sets of preprocessed entities.
Douglas Gregor89d99802010-11-30 06:16:57 +0000469 for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
Douglas Gregor788f5a12010-03-20 00:41:21 +0000470 std::pair<FileID, unsigned> P
471 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
Douglas Gregor89d99802010-11-30 06:16:57 +0000472
Douglas Gregor788f5a12010-03-20 00:41:21 +0000473 ByFileMap[P.first].push_back(*E);
474 }
475 }
476
477 return std::make_pair(ByFileMap[Begin.first].begin(),
478 ByFileMap[Begin.first].end());
479}
480
Douglas Gregorb1373d02010-01-20 20:59:29 +0000481/// \brief Visit the children of the given cursor.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000482///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000483/// \returns true if the visitation should be aborted, false if it
484/// should continue.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000485bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregorc314aa42011-03-02 19:17:03 +0000486 if (clang_isReference(Cursor.kind) &&
487 Cursor.kind != CXCursor_CXXBaseSpecifier) {
Douglas Gregora59e3902010-01-21 23:27:09 +0000488 // By definition, references have no children.
489 return false;
490 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000491
492 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregorb1373d02010-01-20 20:59:29 +0000493 // done.
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000494 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000495
Douglas Gregorb1373d02010-01-20 20:59:29 +0000496 if (clang_isDeclaration(Cursor.kind)) {
497 Decl *D = getCursorDecl(Cursor);
Douglas Gregor06d9b1a2011-04-14 21:41:34 +0000498 if (!D)
499 return false;
500
Ted Kremenek539311e2010-02-18 18:47:01 +0000501 return VisitAttributes(D) || Visit(D);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000502 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000503
Douglas Gregor06d9b1a2011-04-14 21:41:34 +0000504 if (clang_isStatement(Cursor.kind)) {
505 if (Stmt *S = getCursorStmt(Cursor))
506 return Visit(S);
507
508 return false;
509 }
510
511 if (clang_isExpression(Cursor.kind)) {
512 if (Expr *E = getCursorExpr(Cursor))
513 return Visit(E);
514
515 return false;
516 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000517
Douglas Gregorb1373d02010-01-20 20:59:29 +0000518 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000519 CXTranslationUnit tu = getCursorTU(Cursor);
520 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000521
522 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
523 for (unsigned I = 0; I != 2; ++I) {
524 if (VisitOrder[I]) {
525 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
526 RegionOfInterest.isInvalid()) {
527 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
528 TLEnd = CXXUnit->top_level_end();
529 TL != TLEnd; ++TL) {
530 if (Visit(MakeCXCursor(*TL, tu), true))
531 return true;
532 }
533 } else if (VisitDeclContext(
534 CXXUnit->getASTContext().getTranslationUnitDecl()))
Douglas Gregor7b691f332010-01-20 21:13:59 +0000535 return true;
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000536 continue;
Douglas Gregor7b691f332010-01-20 21:13:59 +0000537 }
Bob Wilson3178cb62010-03-19 03:57:57 +0000538
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000539 // Walk the preprocessing record.
540 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
541 // FIXME: Once we have the ability to deserialize a preprocessing record,
542 // do so.
543 PreprocessingRecord::iterator E, EEnd;
544 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
545 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
546 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
547 return true;
548
549 continue;
550 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000551
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000552 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
553 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
554 return true;
555
556 continue;
557 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000558
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000559 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
560 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
561 return true;
562
563 continue;
564 }
Douglas Gregorecdcb882010-10-20 22:00:55 +0000565 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000566 }
567 }
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000568
Douglas Gregor7b691f332010-01-20 21:13:59 +0000569 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000570 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000571
Douglas Gregorc314aa42011-03-02 19:17:03 +0000572 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
573 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
574 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
575 return Visit(BaseTSInfo->getTypeLoc());
576 }
577 }
578 }
579
Douglas Gregorb1373d02010-01-20 20:59:29 +0000580 // Nothing to visit at the moment.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000581 return false;
582}
583
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000584bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
Douglas Gregor13c8ccb2011-04-22 23:49:24 +0000585 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
586 if (Visit(TSInfo->getTypeLoc()))
587 return true;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000588
Ted Kremenek664cffd2010-07-22 11:30:19 +0000589 if (Stmt *Body = B->getBody())
590 return Visit(MakeCXCursor(Body, StmtParent, TU));
591
592 return false;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000593}
594
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000595llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
596 if (RegionOfInterest.isValid()) {
Douglas Gregor66537982010-11-17 17:14:07 +0000597 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000598 if (Range.isInvalid())
599 return llvm::Optional<bool>();
Douglas Gregor66537982010-11-17 17:14:07 +0000600
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000601 switch (CompareRegionOfInterest(Range)) {
602 case RangeBefore:
603 // This declaration comes before the region of interest; skip it.
604 return llvm::Optional<bool>();
605
606 case RangeAfter:
607 // This declaration comes after the region of interest; we're done.
608 return false;
609
610 case RangeOverlap:
611 // This declaration overlaps the region of interest; visit it.
612 break;
613 }
614 }
615 return true;
616}
617
618bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
619 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
620
621 // FIXME: Eventually remove. This part of a hack to support proper
622 // iteration over all Decls contained lexically within an ObjC container.
623 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
624 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
625
626 for ( ; I != E; ++I) {
Ted Kremenek23173d72010-05-18 21:09:07 +0000627 Decl *D = *I;
628 if (D->getLexicalDeclContext() != DC)
629 continue;
Ted Kremenek23173d72010-05-18 21:09:07 +0000630 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000631 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
632 if (!V.hasValue())
633 continue;
634 if (!V.getValue())
635 return false;
Daniel Dunbard52864b2010-02-14 10:02:57 +0000636 if (Visit(Cursor, true))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000637 return true;
638 }
Douglas Gregorb1373d02010-01-20 20:59:29 +0000639 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000640}
641
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000642bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
643 llvm_unreachable("Translation units are visited directly by Visit()");
644 return false;
645}
646
Richard Smith162e1c12011-04-15 14:24:37 +0000647bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
648 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
649 return Visit(TSInfo->getTypeLoc());
650
651 return false;
652}
653
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000654bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
655 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
656 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000657
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000658 return false;
659}
660
661bool CursorVisitor::VisitTagDecl(TagDecl *D) {
662 return VisitDeclContext(D);
663}
664
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000665bool CursorVisitor::VisitClassTemplateSpecializationDecl(
666 ClassTemplateSpecializationDecl *D) {
667 bool ShouldVisitBody = false;
668 switch (D->getSpecializationKind()) {
669 case TSK_Undeclared:
670 case TSK_ImplicitInstantiation:
671 // Nothing to visit
672 return false;
673
674 case TSK_ExplicitInstantiationDeclaration:
675 case TSK_ExplicitInstantiationDefinition:
676 break;
677
678 case TSK_ExplicitSpecialization:
679 ShouldVisitBody = true;
680 break;
681 }
682
683 // Visit the template arguments used in the specialization.
684 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
685 TypeLoc TL = SpecType->getTypeLoc();
686 if (TemplateSpecializationTypeLoc *TSTLoc
687 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
688 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
689 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
690 return true;
691 }
692 }
693
694 if (ShouldVisitBody && VisitCXXRecordDecl(D))
695 return true;
696
697 return false;
698}
699
Douglas Gregor74dbe642010-08-31 19:31:58 +0000700bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
701 ClassTemplatePartialSpecializationDecl *D) {
702 // FIXME: Visit the "outer" template parameter lists on the TagDecl
703 // before visiting these template parameters.
704 if (VisitTemplateParameters(D->getTemplateParameters()))
705 return true;
706
707 // Visit the partial specialization arguments.
708 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
709 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
710 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
711 return true;
712
713 return VisitCXXRecordDecl(D);
714}
715
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000716bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor84b51d72010-09-01 20:16:53 +0000717 // Visit the default argument.
718 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
719 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
720 if (Visit(DefArg->getTypeLoc()))
721 return true;
722
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000723 return false;
724}
725
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000726bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
727 if (Expr *Init = D->getInitExpr())
728 return Visit(MakeCXCursor(Init, StmtParent, TU));
729 return false;
730}
731
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000732bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
733 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
734 if (Visit(TSInfo->getTypeLoc()))
735 return true;
736
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000737 // Visit the nested-name-specifier, if present.
738 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
739 if (VisitNestedNameSpecifierLoc(QualifierLoc))
740 return true;
741
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000742 return false;
743}
744
Douglas Gregora67e03f2010-09-09 21:42:20 +0000745/// \brief Compare two base or member initializers based on their source order.
Sean Huntcbb67482011-01-08 20:30:50 +0000746static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
747 CXXCtorInitializer const * const *X
748 = static_cast<CXXCtorInitializer const * const *>(Xp);
749 CXXCtorInitializer const * const *Y
750 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000751
752 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
753 return -1;
754 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
755 return 1;
756 else
757 return 0;
758}
759
Douglas Gregorb1373d02010-01-20 20:59:29 +0000760bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor01829d32010-08-31 14:41:23 +0000761 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
762 // Visit the function declaration's syntactic components in the order
763 // written. This requires a bit of work.
Abramo Bagnara723df242010-12-14 22:11:44 +0000764 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor01829d32010-08-31 14:41:23 +0000765 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
766
767 // If we have a function declared directly (without the use of a typedef),
768 // visit just the return type. Otherwise, just visit the function's type
769 // now.
770 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
771 (!FTL && Visit(TL)))
772 return true;
773
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000774 // Visit the nested-name-specifier, if present.
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000775 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
776 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000777 return true;
Douglas Gregor01829d32010-08-31 14:41:23 +0000778
779 // Visit the declaration name.
780 if (VisitDeclarationNameInfo(ND->getNameInfo()))
781 return true;
782
783 // FIXME: Visit explicitly-specified template arguments!
784
785 // Visit the function parameters, if we have a function type.
786 if (FTL && VisitFunctionTypeLoc(*FTL, true))
787 return true;
788
789 // FIXME: Attributes?
790 }
791
Francois Pichet8387e2a2011-04-22 22:18:13 +0000792 if (ND->isThisDeclarationADefinition() && !ND->isLateTemplateParsed()) {
Douglas Gregora67e03f2010-09-09 21:42:20 +0000793 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
794 // Find the initializers that were written in the source.
Sean Huntcbb67482011-01-08 20:30:50 +0000795 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregora67e03f2010-09-09 21:42:20 +0000796 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
797 IEnd = Constructor->init_end();
798 I != IEnd; ++I) {
799 if (!(*I)->isWritten())
800 continue;
801
802 WrittenInits.push_back(*I);
803 }
804
805 // Sort the initializers in source order
806 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Sean Huntcbb67482011-01-08 20:30:50 +0000807 &CompareCXXCtorInitializers);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000808
809 // Visit the initializers in source order
810 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Sean Huntcbb67482011-01-08 20:30:50 +0000811 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichet00eb3f92010-12-04 09:14:42 +0000812 if (Init->isAnyMemberInitializer()) {
813 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregora67e03f2010-09-09 21:42:20 +0000814 Init->getMemberLocation(), TU)))
815 return true;
816 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
817 if (Visit(BaseInfo->getTypeLoc()))
818 return true;
819 }
820
821 // Visit the initializer value.
822 if (Expr *Initializer = Init->getInit())
823 if (Visit(MakeCXCursor(Initializer, ND, TU)))
824 return true;
825 }
826 }
827
828 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
829 return true;
830 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000831
Douglas Gregorb1373d02010-01-20 20:59:29 +0000832 return false;
833}
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000834
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000835bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
836 if (VisitDeclaratorDecl(D))
837 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000838
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000839 if (Expr *BitWidth = D->getBitWidth())
840 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000841
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000842 return false;
843}
844
845bool CursorVisitor::VisitVarDecl(VarDecl *D) {
846 if (VisitDeclaratorDecl(D))
847 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000848
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000849 if (Expr *Init = D->getInit())
850 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000851
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000852 return false;
853}
854
Douglas Gregor84b51d72010-09-01 20:16:53 +0000855bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
856 if (VisitDeclaratorDecl(D))
857 return true;
858
859 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
860 if (Expr *DefArg = D->getDefaultArgument())
861 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
862
863 return false;
864}
865
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000866bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
867 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
868 // before visiting these template parameters.
869 if (VisitTemplateParameters(D->getTemplateParameters()))
870 return true;
871
872 return VisitFunctionDecl(D->getTemplatedDecl());
873}
874
Douglas Gregor39d6f072010-08-31 19:02:00 +0000875bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
876 // FIXME: Visit the "outer" template parameter lists on the TagDecl
877 // before visiting these template parameters.
878 if (VisitTemplateParameters(D->getTemplateParameters()))
879 return true;
880
881 return VisitCXXRecordDecl(D->getTemplatedDecl());
882}
883
Douglas Gregor84b51d72010-09-01 20:16:53 +0000884bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
885 if (VisitTemplateParameters(D->getTemplateParameters()))
886 return true;
887
888 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
889 VisitTemplateArgumentLoc(D->getDefaultArgument()))
890 return true;
891
892 return false;
893}
894
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000895bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor4bc1cb62010-03-08 14:59:44 +0000896 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
897 if (Visit(TSInfo->getTypeLoc()))
898 return true;
899
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000900 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000901 PEnd = ND->param_end();
902 P != PEnd; ++P) {
903 if (Visit(MakeCXCursor(*P, TU)))
904 return true;
905 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000906
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000907 if (ND->isThisDeclarationADefinition() &&
908 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
909 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000910
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000911 return false;
912}
913
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000914namespace {
915 struct ContainerDeclsSort {
916 SourceManager &SM;
917 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
918 bool operator()(Decl *A, Decl *B) {
919 SourceLocation L_A = A->getLocStart();
920 SourceLocation L_B = B->getLocStart();
921 assert(L_A.isValid() && L_B.isValid());
922 return SM.isBeforeInTranslationUnit(L_A, L_B);
923 }
924 };
925}
926
Douglas Gregora59e3902010-01-21 23:27:09 +0000927bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000928 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
929 // an @implementation can lexically contain Decls that are not properly
930 // nested in the AST. When we identify such cases, we need to retrofit
931 // this nesting here.
932 if (!DI_current)
933 return VisitDeclContext(D);
934
935 // Scan the Decls that immediately come after the container
936 // in the current DeclContext. If any fall within the
937 // container's lexical region, stash them into a vector
938 // for later processing.
939 llvm::SmallVector<Decl *, 24> DeclsInContainer;
940 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000941 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000942 if (EndLoc.isValid()) {
943 DeclContext::decl_iterator next = *DI_current;
944 while (++next != DE_current) {
945 Decl *D_next = *next;
946 if (!D_next)
947 break;
948 SourceLocation L = D_next->getLocStart();
949 if (!L.isValid())
950 break;
951 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
952 *DI_current = next;
953 DeclsInContainer.push_back(D_next);
954 continue;
955 }
956 break;
957 }
958 }
959
960 // The common case.
961 if (DeclsInContainer.empty())
962 return VisitDeclContext(D);
963
964 // Get all the Decls in the DeclContext, and sort them with the
965 // additional ones we've collected. Then visit them.
966 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
967 I!=E; ++I) {
968 Decl *subDecl = *I;
Ted Kremenek0582c892010-11-02 23:17:51 +0000969 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
970 subDecl->getLocStart().isInvalid())
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000971 continue;
972 DeclsInContainer.push_back(subDecl);
973 }
974
975 // Now sort the Decls so that they appear in lexical order.
976 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
977 ContainerDeclsSort(SM));
978
979 // Now visit the decls.
980 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
981 E = DeclsInContainer.end(); I != E; ++I) {
982 CXCursor Cursor = MakeCXCursor(*I, TU);
983 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
984 if (!V.hasValue())
985 continue;
986 if (!V.getValue())
987 return false;
988 if (Visit(Cursor, true))
989 return true;
990 }
991 return false;
Douglas Gregora59e3902010-01-21 23:27:09 +0000992}
993
Douglas Gregorb1373d02010-01-20 20:59:29 +0000994bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000995 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
996 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000997 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000998
Douglas Gregor78db0cd2010-01-16 15:44:18 +0000999 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1000 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1001 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001002 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001003 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001004
Douglas Gregora59e3902010-01-21 23:27:09 +00001005 return VisitObjCContainerDecl(ND);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001006}
1007
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001008bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1009 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1010 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1011 E = PID->protocol_end(); I != E; ++I, ++PL)
1012 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1013 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001014
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001015 return VisitObjCContainerDecl(PID);
1016}
1017
Ted Kremenek23173d72010-05-18 21:09:07 +00001018bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor83cb9422010-09-09 17:09:21 +00001019 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCallfc929202010-06-04 22:33:30 +00001020 return true;
1021
Ted Kremenek23173d72010-05-18 21:09:07 +00001022 // FIXME: This implements a workaround with @property declarations also being
1023 // installed in the DeclContext for the @interface. Eventually this code
1024 // should be removed.
1025 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1026 if (!CDecl || !CDecl->IsClassExtension())
1027 return false;
1028
1029 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1030 if (!ID)
1031 return false;
1032
1033 IdentifierInfo *PropertyId = PD->getIdentifier();
1034 ObjCPropertyDecl *prevDecl =
1035 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1036
1037 if (!prevDecl)
1038 return false;
1039
1040 // Visit synthesized methods since they will be skipped when visiting
1041 // the @interface.
1042 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001043 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001044 if (Visit(MakeCXCursor(MD, TU)))
1045 return true;
1046
1047 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001048 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001049 if (Visit(MakeCXCursor(MD, TU)))
1050 return true;
1051
1052 return false;
1053}
1054
Douglas Gregorb1373d02010-01-20 20:59:29 +00001055bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001056 // Issue callbacks for super class.
Douglas Gregorb1373d02010-01-20 20:59:29 +00001057 if (D->getSuperClass() &&
1058 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001059 D->getSuperClassLoc(),
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001060 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001061 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001062
Douglas Gregor78db0cd2010-01-16 15:44:18 +00001063 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1064 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1065 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001066 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001067 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001068
Douglas Gregora59e3902010-01-21 23:27:09 +00001069 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001070}
1071
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001072bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1073 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001074}
1075
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001076bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremenekebfa3392010-03-19 20:39:03 +00001077 // 'ID' could be null when dealing with invalid code.
1078 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1079 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1080 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001081
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001082 return VisitObjCImplDecl(D);
1083}
1084
1085bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1086#if 0
1087 // Issue callbacks for super class.
1088 // FIXME: No source location information!
1089 if (D->getSuperClass() &&
1090 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001091 D->getSuperClassLoc(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001092 TU)))
1093 return true;
1094#endif
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001095
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001096 return VisitObjCImplDecl(D);
1097}
1098
1099bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1100 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1101 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1102 E = D->protocol_end();
1103 I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001104 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001105 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001106
1107 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001108}
1109
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001110bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1111 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1112 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1113 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001114
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001115 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001116}
1117
Douglas Gregora4ffd852010-11-17 01:03:52 +00001118bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1119 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1120 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1121
1122 return false;
1123}
1124
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00001125bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1126 return VisitDeclContext(D);
1127}
1128
Douglas Gregor69319002010-08-31 23:48:11 +00001129bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001130 // Visit nested-name-specifier.
Douglas Gregor0cfaf6a2011-02-25 17:08:07 +00001131 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1132 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001133 return true;
Douglas Gregor69319002010-08-31 23:48:11 +00001134
1135 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1136 D->getTargetNameLoc(), TU));
1137}
1138
Douglas Gregor7e242562010-09-01 19:52:22 +00001139bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001140 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001141 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1142 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001143 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001144 }
Douglas Gregor7e242562010-09-01 19:52:22 +00001145
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001146 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1147 return true;
1148
Douglas Gregor7e242562010-09-01 19:52:22 +00001149 return VisitDeclarationNameInfo(D->getNameInfo());
1150}
1151
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001152bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001153 // Visit nested-name-specifier.
Douglas Gregordb992412011-02-25 16:33:46 +00001154 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1155 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001156 return true;
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001157
1158 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1159 D->getIdentLocation(), TU));
1160}
1161
Douglas Gregor7e242562010-09-01 19:52:22 +00001162bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001163 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001164 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1165 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001166 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001167 }
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001168
Douglas Gregor7e242562010-09-01 19:52:22 +00001169 return VisitDeclarationNameInfo(D->getNameInfo());
1170}
1171
1172bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1173 UnresolvedUsingTypenameDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001174 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001175 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1176 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001177 return true;
1178
Douglas Gregor7e242562010-09-01 19:52:22 +00001179 return false;
1180}
1181
Douglas Gregor01829d32010-08-31 14:41:23 +00001182bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1183 switch (Name.getName().getNameKind()) {
1184 case clang::DeclarationName::Identifier:
1185 case clang::DeclarationName::CXXLiteralOperatorName:
1186 case clang::DeclarationName::CXXOperatorName:
1187 case clang::DeclarationName::CXXUsingDirective:
1188 return false;
1189
1190 case clang::DeclarationName::CXXConstructorName:
1191 case clang::DeclarationName::CXXDestructorName:
1192 case clang::DeclarationName::CXXConversionFunctionName:
1193 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1194 return Visit(TSInfo->getTypeLoc());
1195 return false;
1196
1197 case clang::DeclarationName::ObjCZeroArgSelector:
1198 case clang::DeclarationName::ObjCOneArgSelector:
1199 case clang::DeclarationName::ObjCMultiArgSelector:
1200 // FIXME: Per-identifier location info?
1201 return false;
1202 }
1203
1204 return false;
1205}
1206
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001207bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1208 SourceRange Range) {
1209 // FIXME: This whole routine is a hack to work around the lack of proper
1210 // source information in nested-name-specifiers (PR5791). Since we do have
1211 // a beginning source location, we can visit the first component of the
1212 // nested-name-specifier, if it's a single-token component.
1213 if (!NNS)
1214 return false;
1215
1216 // Get the first component in the nested-name-specifier.
1217 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1218 NNS = Prefix;
1219
1220 switch (NNS->getKind()) {
1221 case NestedNameSpecifier::Namespace:
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001222 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1223 TU));
1224
Douglas Gregor14aba762011-02-24 02:36:08 +00001225 case NestedNameSpecifier::NamespaceAlias:
1226 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1227 Range.getBegin(), TU));
1228
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001229 case NestedNameSpecifier::TypeSpec: {
1230 // If the type has a form where we know that the beginning of the source
1231 // range matches up with a reference cursor. Visit the appropriate reference
1232 // cursor.
John McCallf4c73712011-01-19 06:33:43 +00001233 const Type *T = NNS->getAsType();
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001234 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1235 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1236 if (const TagType *Tag = dyn_cast<TagType>(T))
1237 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1238 if (const TemplateSpecializationType *TST
1239 = dyn_cast<TemplateSpecializationType>(T))
1240 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1241 break;
1242 }
1243
1244 case NestedNameSpecifier::TypeSpecWithTemplate:
1245 case NestedNameSpecifier::Global:
1246 case NestedNameSpecifier::Identifier:
1247 break;
1248 }
1249
1250 return false;
1251}
1252
Douglas Gregordc355712011-02-25 00:36:19 +00001253bool
1254CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1255 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1256 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1257 Qualifiers.push_back(Qualifier);
1258
1259 while (!Qualifiers.empty()) {
1260 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1261 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1262 switch (NNS->getKind()) {
1263 case NestedNameSpecifier::Namespace:
1264 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001265 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001266 TU)))
1267 return true;
1268
1269 break;
1270
1271 case NestedNameSpecifier::NamespaceAlias:
1272 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001273 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001274 TU)))
1275 return true;
1276
1277 break;
1278
1279 case NestedNameSpecifier::TypeSpec:
1280 case NestedNameSpecifier::TypeSpecWithTemplate:
1281 if (Visit(Q.getTypeLoc()))
1282 return true;
1283
1284 break;
1285
1286 case NestedNameSpecifier::Global:
1287 case NestedNameSpecifier::Identifier:
1288 break;
1289 }
1290 }
1291
1292 return false;
1293}
1294
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001295bool CursorVisitor::VisitTemplateParameters(
1296 const TemplateParameterList *Params) {
1297 if (!Params)
1298 return false;
1299
1300 for (TemplateParameterList::const_iterator P = Params->begin(),
1301 PEnd = Params->end();
1302 P != PEnd; ++P) {
1303 if (Visit(MakeCXCursor(*P, TU)))
1304 return true;
1305 }
1306
1307 return false;
1308}
1309
Douglas Gregor0b36e612010-08-31 20:37:03 +00001310bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1311 switch (Name.getKind()) {
1312 case TemplateName::Template:
1313 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1314
1315 case TemplateName::OverloadedTemplate:
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001316 // Visit the overloaded template set.
1317 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1318 return true;
1319
Douglas Gregor0b36e612010-08-31 20:37:03 +00001320 return false;
1321
1322 case TemplateName::DependentTemplate:
1323 // FIXME: Visit nested-name-specifier.
1324 return false;
1325
1326 case TemplateName::QualifiedTemplate:
1327 // FIXME: Visit nested-name-specifier.
1328 return Visit(MakeCursorTemplateRef(
1329 Name.getAsQualifiedTemplateName()->getDecl(),
1330 Loc, TU));
Douglas Gregor1aee05d2011-01-15 06:45:20 +00001331
1332 case TemplateName::SubstTemplateTemplateParmPack:
1333 return Visit(MakeCursorTemplateRef(
1334 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1335 Loc, TU));
Douglas Gregor0b36e612010-08-31 20:37:03 +00001336 }
1337
1338 return false;
1339}
1340
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001341bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1342 switch (TAL.getArgument().getKind()) {
1343 case TemplateArgument::Null:
1344 case TemplateArgument::Integral:
Douglas Gregor87dd6972010-12-20 16:52:59 +00001345 case TemplateArgument::Pack:
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001346 return false;
1347
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001348 case TemplateArgument::Type:
1349 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1350 return Visit(TSInfo->getTypeLoc());
1351 return false;
1352
1353 case TemplateArgument::Declaration:
1354 if (Expr *E = TAL.getSourceDeclExpression())
1355 return Visit(MakeCXCursor(E, StmtParent, TU));
1356 return false;
1357
1358 case TemplateArgument::Expression:
1359 if (Expr *E = TAL.getSourceExpression())
1360 return Visit(MakeCXCursor(E, StmtParent, TU));
1361 return false;
1362
1363 case TemplateArgument::Template:
Douglas Gregora7fc9012011-01-05 18:58:31 +00001364 case TemplateArgument::TemplateExpansion:
Douglas Gregorb6744ef2011-03-02 17:09:35 +00001365 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1366 return true;
1367
Douglas Gregora7fc9012011-01-05 18:58:31 +00001368 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregor0b36e612010-08-31 20:37:03 +00001369 TAL.getTemplateNameLoc());
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001370 }
1371
1372 return false;
1373}
1374
Ted Kremeneka0536d82010-05-07 01:04:29 +00001375bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1376 return VisitDeclContext(D);
1377}
1378
Douglas Gregor01829d32010-08-31 14:41:23 +00001379bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1380 return Visit(TL.getUnqualifiedLoc());
1381}
1382
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001383bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00001384 ASTContext &Context = AU->getASTContext();
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001385
1386 // Some builtin types (such as Objective-C's "id", "sel", and
1387 // "Class") have associated declarations. Create cursors for those.
1388 QualType VisitType;
1389 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001390 case BuiltinType::Void:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001391 case BuiltinType::Bool:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001392 case BuiltinType::Char_U:
1393 case BuiltinType::UChar:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001394 case BuiltinType::Char16:
1395 case BuiltinType::Char32:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001396 case BuiltinType::UShort:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001397 case BuiltinType::UInt:
1398 case BuiltinType::ULong:
1399 case BuiltinType::ULongLong:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001400 case BuiltinType::UInt128:
1401 case BuiltinType::Char_S:
1402 case BuiltinType::SChar:
Chris Lattner3f59c972010-12-25 23:25:43 +00001403 case BuiltinType::WChar_U:
1404 case BuiltinType::WChar_S:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001405 case BuiltinType::Short:
1406 case BuiltinType::Int:
1407 case BuiltinType::Long:
1408 case BuiltinType::LongLong:
1409 case BuiltinType::Int128:
1410 case BuiltinType::Float:
1411 case BuiltinType::Double:
1412 case BuiltinType::LongDouble:
1413 case BuiltinType::NullPtr:
1414 case BuiltinType::Overload:
John McCall864c0412011-04-26 20:42:42 +00001415 case BuiltinType::BoundMember:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001416 case BuiltinType::Dependent:
John McCall1de4d4e2011-04-07 08:22:57 +00001417 case BuiltinType::UnknownAny:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001418 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001419
Ted Kremenekc4174cc2010-02-18 18:52:18 +00001420 case BuiltinType::ObjCId:
1421 VisitType = Context.getObjCIdType();
1422 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001423
1424 case BuiltinType::ObjCClass:
1425 VisitType = Context.getObjCClassType();
1426 break;
1427
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001428 case BuiltinType::ObjCSel:
1429 VisitType = Context.getObjCSelType();
1430 break;
1431 }
1432
1433 if (!VisitType.isNull()) {
1434 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001435 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001436 TU));
1437 }
1438
1439 return false;
1440}
1441
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001442bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
Richard Smith162e1c12011-04-15 14:24:37 +00001443 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001444}
1445
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001446bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1447 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1448}
1449
1450bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1451 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1452}
1453
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001454bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Chandler Carruth960d13d2011-05-01 09:53:37 +00001455 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001456}
1457
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001458bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1459 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1460 return true;
1461
John McCallc12c5bb2010-05-15 11:32:37 +00001462 return false;
1463}
1464
1465bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1466 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1467 return true;
1468
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001469 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1470 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1471 TU)))
1472 return true;
1473 }
1474
1475 return false;
1476}
1477
1478bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCallc12c5bb2010-05-15 11:32:37 +00001479 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001480}
1481
Abramo Bagnara075f8f12010-12-10 16:29:40 +00001482bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1483 return Visit(TL.getInnerLoc());
1484}
1485
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001486bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1487 return Visit(TL.getPointeeLoc());
1488}
1489
1490bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1491 return Visit(TL.getPointeeLoc());
1492}
1493
1494bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1495 return Visit(TL.getPointeeLoc());
1496}
1497
1498bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001499 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001500}
1501
1502bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001503 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001504}
1505
Douglas Gregor01829d32010-08-31 14:41:23 +00001506bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1507 bool SkipResultType) {
1508 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001509 return true;
1510
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001511 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek5dbacb42010-04-07 00:27:13 +00001512 if (Decl *D = TL.getArg(I))
1513 if (Visit(MakeCXCursor(D, TU)))
1514 return true;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001515
1516 return false;
1517}
1518
1519bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1520 if (Visit(TL.getElementLoc()))
1521 return true;
1522
1523 if (Expr *Size = TL.getSizeExpr())
1524 return Visit(MakeCXCursor(Size, StmtParent, TU));
1525
1526 return false;
1527}
1528
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001529bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1530 TemplateSpecializationTypeLoc TL) {
Douglas Gregor0b36e612010-08-31 20:37:03 +00001531 // Visit the template name.
1532 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1533 TL.getTemplateNameLoc()))
1534 return true;
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001535
1536 // Visit the template arguments.
1537 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1538 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1539 return true;
1540
1541 return false;
1542}
1543
Douglas Gregor2332c112010-01-21 20:48:56 +00001544bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1545 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1546}
1547
1548bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1549 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1550 return Visit(TSInfo->getTypeLoc());
1551
1552 return false;
1553}
1554
Douglas Gregor2494dd02011-03-01 01:34:45 +00001555bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1556 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1557 return true;
1558
1559 return false;
1560}
1561
Douglas Gregor94fdffa2011-03-01 20:11:18 +00001562bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1563 DependentTemplateSpecializationTypeLoc TL) {
1564 // Visit the nested-name-specifier, if there is one.
1565 if (TL.getQualifierLoc() &&
1566 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1567 return true;
1568
1569 // Visit the template arguments.
1570 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1571 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1572 return true;
1573
1574 return false;
1575}
1576
Douglas Gregor9e876872011-03-01 18:12:44 +00001577bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1578 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1579 return true;
1580
1581 return Visit(TL.getNamedTypeLoc());
1582}
1583
Douglas Gregor7536dd52010-12-20 02:24:11 +00001584bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1585 return Visit(TL.getPatternLoc());
1586}
1587
Ted Kremenek3064ef92010-08-27 21:34:58 +00001588bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001589 // Visit the nested-name-specifier, if present.
1590 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1591 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1592 return true;
1593
Ted Kremenek3064ef92010-08-27 21:34:58 +00001594 if (D->isDefinition()) {
1595 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1596 E = D->bases_end(); I != E; ++I) {
1597 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1598 return true;
1599 }
1600 }
1601
1602 return VisitTagDecl(D);
1603}
1604
Ted Kremenek09dfa372010-02-18 05:46:33 +00001605bool CursorVisitor::VisitAttributes(Decl *D) {
Sean Huntcf807c42010-08-18 23:23:40 +00001606 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1607 i != e; ++i)
1608 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek09dfa372010-02-18 05:46:33 +00001609 return true;
1610
1611 return false;
1612}
1613
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001614//===----------------------------------------------------------------------===//
1615// Data-recursive visitor methods.
1616//===----------------------------------------------------------------------===//
1617
Ted Kremenek28a71942010-11-13 00:36:47 +00001618namespace {
Ted Kremenek035dc412010-11-13 00:36:50 +00001619#define DEF_JOB(NAME, DATA, KIND)\
1620class NAME : public VisitorJob {\
1621public:\
1622 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1623 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenekf64d8032010-11-18 00:02:32 +00001624 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek035dc412010-11-13 00:36:50 +00001625};
1626
1627DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1628DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001629DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001630DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek60608ec2010-11-17 00:50:47 +00001631DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1632 ExplicitTemplateArgsVisitKind)
Douglas Gregor94d96292011-01-19 20:34:17 +00001633DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001634#undef DEF_JOB
1635
1636class DeclVisit : public VisitorJob {
1637public:
1638 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1639 VisitorJob(parent, VisitorJob::DeclVisitKind,
1640 d, isFirst ? (void*) 1 : (void*) 0) {}
1641 static bool classof(const VisitorJob *VJ) {
Ted Kremenek82f3c502010-11-15 22:23:26 +00001642 return VJ->getKind() == DeclVisitKind;
Ted Kremenek035dc412010-11-13 00:36:50 +00001643 }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001644 Decl *get() const { return static_cast<Decl*>(data[0]); }
1645 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek035dc412010-11-13 00:36:50 +00001646};
Ted Kremenek035dc412010-11-13 00:36:50 +00001647class TypeLocVisit : public VisitorJob {
1648public:
1649 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1650 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1651 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1652
1653 static bool classof(const VisitorJob *VJ) {
1654 return VJ->getKind() == TypeLocVisitKind;
1655 }
1656
Ted Kremenek82f3c502010-11-15 22:23:26 +00001657 TypeLoc get() const {
Ted Kremenekf64d8032010-11-18 00:02:32 +00001658 QualType T = QualType::getFromOpaquePtr(data[0]);
1659 return TypeLoc(T, data[1]);
Ted Kremenek035dc412010-11-13 00:36:50 +00001660 }
1661};
1662
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001663class LabelRefVisit : public VisitorJob {
1664public:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001665 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1666 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001667 labelLoc.getPtrEncoding()) {}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001668
1669 static bool classof(const VisitorJob *VJ) {
1670 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1671 }
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001672 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001673 SourceLocation getLoc() const {
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001674 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001675};
1676class NestedNameSpecifierVisit : public VisitorJob {
1677public:
1678 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1679 CXCursor parent)
1680 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001681 NS, R.getBegin().getPtrEncoding(),
1682 R.getEnd().getPtrEncoding()) {}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001683 static bool classof(const VisitorJob *VJ) {
1684 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1685 }
1686 NestedNameSpecifier *get() const {
1687 return static_cast<NestedNameSpecifier*>(data[0]);
1688 }
1689 SourceRange getSourceRange() const {
1690 SourceLocation A =
1691 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1692 SourceLocation B =
1693 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1694 return SourceRange(A, B);
1695 }
1696};
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001697
1698class NestedNameSpecifierLocVisit : public VisitorJob {
1699public:
1700 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1701 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1702 Qualifier.getNestedNameSpecifier(),
1703 Qualifier.getOpaqueData()) { }
1704
1705 static bool classof(const VisitorJob *VJ) {
1706 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1707 }
1708
1709 NestedNameSpecifierLoc get() const {
1710 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1711 data[1]);
1712 }
1713};
1714
Ted Kremenekf64d8032010-11-18 00:02:32 +00001715class DeclarationNameInfoVisit : public VisitorJob {
1716public:
1717 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1718 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1719 static bool classof(const VisitorJob *VJ) {
1720 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1721 }
1722 DeclarationNameInfo get() const {
1723 Stmt *S = static_cast<Stmt*>(data[0]);
1724 switch (S->getStmtClass()) {
1725 default:
1726 llvm_unreachable("Unhandled Stmt");
1727 case Stmt::CXXDependentScopeMemberExprClass:
1728 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1729 case Stmt::DependentScopeDeclRefExprClass:
1730 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1731 }
1732 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001733};
Ted Kremenekcdba6592010-11-18 00:42:18 +00001734class MemberRefVisit : public VisitorJob {
1735public:
1736 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001738 L.getPtrEncoding()) {}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001739 static bool classof(const VisitorJob *VJ) {
1740 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1741 }
1742 FieldDecl *get() const {
1743 return static_cast<FieldDecl*>(data[0]);
1744 }
1745 SourceLocation getLoc() const {
1746 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1747 }
1748};
Ted Kremenek28a71942010-11-13 00:36:47 +00001749class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1750 VisitorWorkList &WL;
1751 CXCursor Parent;
1752public:
1753 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1754 : WL(wl), Parent(parent) {}
1755
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001756 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001757 void VisitBlockExpr(BlockExpr *B);
Ted Kremenek28a71942010-11-13 00:36:47 +00001758 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenek083c7e22010-11-13 05:38:03 +00001759 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001760 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001761 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001762 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001763 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001764 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001765 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001766 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001767 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek55b933a2010-11-17 00:50:36 +00001768 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001769 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001770 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek035dc412010-11-13 00:36:50 +00001771 void VisitDeclStmt(DeclStmt *S);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001772 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001773 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001774 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1775 void VisitForStmt(ForStmt *FS);
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001776 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenek28a71942010-11-13 00:36:47 +00001777 void VisitIfStmt(IfStmt *If);
1778 void VisitInitListExpr(InitListExpr *IE);
1779 void VisitMemberExpr(MemberExpr *M);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001780 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001781 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001782 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1783 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00001784 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001785 void VisitStmt(Stmt *S);
1786 void VisitSwitchStmt(SwitchStmt *S);
1787 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek2939b6f2010-11-17 00:50:50 +00001788 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet6ad6f282010-12-07 00:08:36 +00001789 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
John Wiegley21ff2e52011-04-28 00:16:57 +00001790 void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
John Wiegley55262202011-04-25 06:54:41 +00001791 void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001792 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenek9d3bf792010-11-17 00:50:43 +00001793 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor94d96292011-01-19 20:34:17 +00001794 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregoree8aff02011-01-04 17:33:58 +00001795
Ted Kremenek28a71942010-11-13 00:36:47 +00001796private:
Ted Kremenekf64d8032010-11-18 00:02:32 +00001797 void AddDeclarationNameInfo(Stmt *S);
1798 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001799 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek60608ec2010-11-17 00:50:47 +00001800 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001801 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenek28a71942010-11-13 00:36:47 +00001802 void AddStmt(Stmt *S);
Ted Kremenek035dc412010-11-13 00:36:50 +00001803 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenek28a71942010-11-13 00:36:47 +00001804 void AddTypeLoc(TypeSourceInfo *TI);
1805 void EnqueueChildren(Stmt *S);
1806};
1807} // end anonyous namespace
1808
Ted Kremenekf64d8032010-11-18 00:02:32 +00001809void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1810 // 'S' should always be non-null, since it comes from the
1811 // statement we are visiting.
1812 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1813}
1814void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1815 SourceRange R) {
1816 if (N)
1817 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1818}
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001819
1820void
1821EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1822 if (Qualifier)
1823 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1824}
1825
Ted Kremenek28a71942010-11-13 00:36:47 +00001826void EnqueueVisitor::AddStmt(Stmt *S) {
1827 if (S)
1828 WL.push_back(StmtVisit(S, Parent));
1829}
Ted Kremenek035dc412010-11-13 00:36:50 +00001830void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001831 if (D)
Ted Kremenek035dc412010-11-13 00:36:50 +00001832 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenek28a71942010-11-13 00:36:47 +00001833}
Ted Kremenek60608ec2010-11-17 00:50:47 +00001834void EnqueueVisitor::
1835 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1836 if (A)
1837 WL.push_back(ExplicitTemplateArgsVisit(
1838 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1839}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001840void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1841 if (D)
1842 WL.push_back(MemberRefVisit(D, L, Parent));
1843}
Ted Kremenek28a71942010-11-13 00:36:47 +00001844void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1845 if (TI)
1846 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1847 }
1848void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremeneka6b70432010-11-12 21:34:09 +00001849 unsigned size = WL.size();
John McCall7502c1d2011-02-13 04:07:26 +00001850 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001851 AddStmt(*Child);
Ted Kremeneka6b70432010-11-12 21:34:09 +00001852 }
1853 if (size == WL.size())
1854 return;
1855 // Now reverse the entries we just added. This will match the DFS
1856 // ordering performed by the worklist.
1857 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1858 std::reverse(I, E);
1859}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001860void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1861 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1862}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001863void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1864 AddDecl(B->getBlockDecl());
1865}
Ted Kremenek28a71942010-11-13 00:36:47 +00001866void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1867 EnqueueChildren(E);
1868 AddTypeLoc(E->getTypeSourceInfo());
1869}
Ted Kremenek083c7e22010-11-13 05:38:03 +00001870void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1871 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1872 E = S->body_rend(); I != E; ++I) {
1873 AddStmt(*I);
1874 }
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001875}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001876void EnqueueVisitor::
1877VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1878 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1879 AddDeclarationNameInfo(E);
Douglas Gregor7c3179c2011-02-28 18:50:33 +00001880 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1881 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001882 if (!E->isImplicitAccess())
1883 AddStmt(E->getBase());
1884}
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001885void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1886 // Enqueue the initializer or constructor arguments.
1887 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1888 AddStmt(E->getConstructorArg(I-1));
1889 // Enqueue the array size, if any.
1890 AddStmt(E->getArraySize());
1891 // Enqueue the allocated type.
1892 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1893 // Enqueue the placement arguments.
1894 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1895 AddStmt(E->getPlacementArg(I-1));
1896}
Ted Kremenek28a71942010-11-13 00:36:47 +00001897void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenek8b8d8c92010-11-13 05:55:56 +00001898 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1899 AddStmt(CE->getArg(I-1));
Ted Kremenek28a71942010-11-13 00:36:47 +00001900 AddStmt(CE->getCallee());
1901 AddStmt(CE->getArg(0));
1902}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001903void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1904 // Visit the name of the type being destroyed.
1905 AddTypeLoc(E->getDestroyedTypeInfo());
1906 // Visit the scope type that looks disturbingly like the nested-name-specifier
1907 // but isn't.
1908 AddTypeLoc(E->getScopeTypeInfo());
1909 // Visit the nested-name-specifier.
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001910 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1911 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001912 // Visit base expression.
1913 AddStmt(E->getBase());
1914}
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001915void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1916 AddTypeLoc(E->getTypeSourceInfo());
1917}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001918void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1919 EnqueueChildren(E);
1920 AddTypeLoc(E->getTypeSourceInfo());
1921}
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001922void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1923 EnqueueChildren(E);
1924 if (E->isTypeOperand())
1925 AddTypeLoc(E->getTypeOperandSourceInfo());
1926}
Ted Kremenek55b933a2010-11-17 00:50:36 +00001927
1928void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1929 *E) {
1930 EnqueueChildren(E);
1931 AddTypeLoc(E->getTypeSourceInfo());
1932}
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001933void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1934 EnqueueChildren(E);
1935 if (E->isTypeOperand())
1936 AddTypeLoc(E->getTypeOperandSourceInfo());
1937}
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001938void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00001939 if (DR->hasExplicitTemplateArgs()) {
1940 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1941 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001942 WL.push_back(DeclRefExprParts(DR, Parent));
1943}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001944void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1945 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1946 AddDeclarationNameInfo(E);
Douglas Gregor00cf3cc2011-02-25 20:49:16 +00001947 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenekf64d8032010-11-18 00:02:32 +00001948}
Ted Kremenek035dc412010-11-13 00:36:50 +00001949void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1950 unsigned size = WL.size();
1951 bool isFirst = true;
1952 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1953 D != DEnd; ++D) {
1954 AddDecl(*D, isFirst);
1955 isFirst = false;
1956 }
1957 if (size == WL.size())
1958 return;
1959 // Now reverse the entries we just added. This will match the DFS
1960 // ordering performed by the worklist.
1961 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1962 std::reverse(I, E);
1963}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001964void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1965 AddStmt(E->getInit());
1966 typedef DesignatedInitExpr::Designator Designator;
1967 for (DesignatedInitExpr::reverse_designators_iterator
1968 D = E->designators_rbegin(), DEnd = E->designators_rend();
1969 D != DEnd; ++D) {
1970 if (D->isFieldDesignator()) {
1971 if (FieldDecl *Field = D->getField())
1972 AddMemberRef(Field, D->getFieldLoc());
1973 continue;
1974 }
1975 if (D->isArrayDesignator()) {
1976 AddStmt(E->getArrayIndex(*D));
1977 continue;
1978 }
1979 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1980 AddStmt(E->getArrayRangeEnd(*D));
1981 AddStmt(E->getArrayRangeStart(*D));
1982 }
1983}
Ted Kremenek28a71942010-11-13 00:36:47 +00001984void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1985 EnqueueChildren(E);
1986 AddTypeLoc(E->getTypeInfoAsWritten());
1987}
1988void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1989 AddStmt(FS->getBody());
1990 AddStmt(FS->getInc());
1991 AddStmt(FS->getCond());
1992 AddDecl(FS->getConditionVariable());
1993 AddStmt(FS->getInit());
1994}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001995void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1996 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1997}
Ted Kremenek28a71942010-11-13 00:36:47 +00001998void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
1999 AddStmt(If->getElse());
2000 AddStmt(If->getThen());
2001 AddStmt(If->getCond());
2002 AddDecl(If->getConditionVariable());
2003}
2004void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
2005 // We care about the syntactic form of the initializer list, only.
2006 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2007 IE = Syntactic;
2008 EnqueueChildren(IE);
2009}
2010void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor89629a72010-11-17 17:15:08 +00002011 WL.push_back(MemberExprParts(M, Parent));
2012
2013 // If the base of the member access expression is an implicit 'this', don't
2014 // visit it.
2015 // FIXME: If we ever want to show these implicit accesses, this will be
2016 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor75e85042011-03-02 21:06:53 +00002017 if (!M->isImplicitAccess())
2018 AddStmt(M->getBase());
Ted Kremenek28a71942010-11-13 00:36:47 +00002019}
Ted Kremenek73d15c42010-11-13 01:09:29 +00002020void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2021 AddTypeLoc(E->getEncodedTypeSourceInfo());
2022}
Ted Kremenek28a71942010-11-13 00:36:47 +00002023void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2024 EnqueueChildren(M);
2025 AddTypeLoc(M->getClassReceiverTypeInfo());
2026}
Ted Kremenekcdba6592010-11-18 00:42:18 +00002027void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2028 // Visit the components of the offsetof expression.
2029 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2030 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2031 const OffsetOfNode &Node = E->getComponent(I-1);
2032 switch (Node.getKind()) {
2033 case OffsetOfNode::Array:
2034 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2035 break;
2036 case OffsetOfNode::Field:
Abramo Bagnara06dec892011-03-12 09:45:03 +00002037 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenekcdba6592010-11-18 00:42:18 +00002038 break;
2039 case OffsetOfNode::Identifier:
2040 case OffsetOfNode::Base:
2041 continue;
2042 }
2043 }
2044 // Visit the type into which we're computing the offset.
2045 AddTypeLoc(E->getTypeSourceInfo());
2046}
Ted Kremenek28a71942010-11-13 00:36:47 +00002047void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00002048 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenek60458782010-11-12 21:34:16 +00002049 WL.push_back(OverloadExprParts(E, Parent));
2050}
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00002051void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2052 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00002053 EnqueueChildren(E);
2054 if (E->isArgumentType())
2055 AddTypeLoc(E->getArgumentTypeInfo());
2056}
Ted Kremenek28a71942010-11-13 00:36:47 +00002057void EnqueueVisitor::VisitStmt(Stmt *S) {
2058 EnqueueChildren(S);
2059}
2060void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2061 AddStmt(S->getBody());
2062 AddStmt(S->getCond());
2063 AddDecl(S->getConditionVariable());
2064}
Ted Kremenekfafa75a2010-11-17 00:50:39 +00002065
Ted Kremenek28a71942010-11-13 00:36:47 +00002066void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2067 AddStmt(W->getBody());
2068 AddStmt(W->getCond());
2069 AddDecl(W->getConditionVariable());
2070}
John Wiegley21ff2e52011-04-28 00:16:57 +00002071
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 Wiegley21ff2e52011-04-28 00:16:57 +00002081void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2082 AddTypeLoc(E->getQueriedTypeSourceInfo());
2083}
2084
John Wiegley55262202011-04-25 06:54:41 +00002085void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2086 EnqueueChildren(E);
2087}
2088
Ted Kremenek28a71942010-11-13 00:36:47 +00002089void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2090 VisitOverloadExpr(U);
2091 if (!U->isImplicitAccess())
2092 AddStmt(U->getBase());
2093}
Ted Kremenek9d3bf792010-11-17 00:50:43 +00002094void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2095 AddStmt(E->getSubExpr());
2096 AddTypeLoc(E->getWrittenTypeInfo());
2097}
Douglas Gregor94d96292011-01-19 20:34:17 +00002098void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2099 WL.push_back(SizeOfPackExprParts(E, Parent));
2100}
Ted Kremenek60458782010-11-12 21:34:16 +00002101
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002102void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenek28a71942010-11-13 00:36:47 +00002103 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002104}
2105
2106bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2107 if (RegionOfInterest.isValid()) {
2108 SourceRange Range = getRawCursorExtent(C);
2109 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2110 return false;
2111 }
2112 return true;
2113}
2114
2115bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2116 while (!WL.empty()) {
2117 // Dequeue the worklist item.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002118 VisitorJob LI = WL.back();
2119 WL.pop_back();
2120
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002121 // Set the Parent field, then back to its old value once we're done.
2122 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2123
2124 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00002125 case VisitorJob::DeclVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002126 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenekf1107452010-11-12 18:26:56 +00002127 if (!D)
2128 continue;
2129
2130 // For now, perform default visitation for Decls.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002131 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenekf1107452010-11-12 18:26:56 +00002132 return true;
2133
2134 continue;
2135 }
Ted Kremenek60608ec2010-11-17 00:50:47 +00002136 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2137 const ExplicitTemplateArgumentList *ArgList =
2138 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2139 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2140 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2141 Arg != ArgEnd; ++Arg) {
2142 if (VisitTemplateArgumentLoc(*Arg))
2143 return true;
2144 }
2145 continue;
2146 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002147 case VisitorJob::TypeLocVisitKind: {
2148 // Perform default visitation for TypeLocs.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002149 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002150 return true;
2151 continue;
2152 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002153 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002154 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremeneke7455012011-02-23 04:54:51 +00002155 if (LabelStmt *stmt = LS->getStmt()) {
2156 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2157 TU))) {
2158 return true;
2159 }
2160 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002161 continue;
2162 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002163
Ted Kremenekf64d8032010-11-18 00:02:32 +00002164 case VisitorJob::NestedNameSpecifierVisitKind: {
2165 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2166 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2167 return true;
2168 continue;
2169 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002170
2171 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2172 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2173 if (VisitNestedNameSpecifierLoc(V->get()))
2174 return true;
2175 continue;
2176 }
2177
Ted Kremenekf64d8032010-11-18 00:02:32 +00002178 case VisitorJob::DeclarationNameInfoVisitKind: {
2179 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2180 ->get()))
2181 return true;
2182 continue;
2183 }
Ted Kremenekcdba6592010-11-18 00:42:18 +00002184 case VisitorJob::MemberRefVisitKind: {
2185 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2186 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2187 return true;
2188 continue;
2189 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002190 case VisitorJob::StmtVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002191 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002192 if (!S)
2193 continue;
2194
Ted Kremenekf1107452010-11-12 18:26:56 +00002195 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002196 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenekcdba6592010-11-18 00:42:18 +00002197 if (!IsInRegionOfInterest(Cursor))
2198 continue;
2199 switch (Visitor(Cursor, Parent, ClientData)) {
2200 case CXChildVisit_Break: return true;
2201 case CXChildVisit_Continue: break;
2202 case CXChildVisit_Recurse:
2203 EnqueueWorkList(WL, S);
Ted Kremenek82f3c502010-11-15 22:23:26 +00002204 break;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002205 }
Ted Kremenek82f3c502010-11-15 22:23:26 +00002206 continue;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002207 }
2208 case VisitorJob::MemberExprPartsKind: {
2209 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002210 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002211
2212 // Visit the nested-name-specifier
Douglas Gregor40d96a62011-02-28 21:54:11 +00002213 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2214 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002215 return true;
2216
2217 // Visit the declaration name.
2218 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2219 return true;
2220
2221 // Visit the explicitly-specified template arguments, if any.
2222 if (M->hasExplicitTemplateArgs()) {
2223 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2224 *ArgEnd = Arg + M->getNumTemplateArgs();
2225 Arg != ArgEnd; ++Arg) {
2226 if (VisitTemplateArgumentLoc(*Arg))
2227 return true;
2228 }
2229 }
2230 continue;
2231 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002232 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002233 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002234 // Visit nested-name-specifier, if present.
Douglas Gregor40d96a62011-02-28 21:54:11 +00002235 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2236 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002237 return true;
2238 // Visit declaration name.
2239 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2240 return true;
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002241 continue;
2242 }
Ted Kremenek60458782010-11-12 21:34:16 +00002243 case VisitorJob::OverloadExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002244 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenek60458782010-11-12 21:34:16 +00002245 // Visit the nested-name-specifier.
Douglas Gregor4c9be892011-02-28 20:01:57 +00002246 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2247 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek60458782010-11-12 21:34:16 +00002248 return true;
2249 // Visit the declaration name.
2250 if (VisitDeclarationNameInfo(O->getNameInfo()))
2251 return true;
2252 // Visit the overloaded declaration reference.
2253 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2254 return true;
Ted Kremenek60458782010-11-12 21:34:16 +00002255 continue;
2256 }
Douglas Gregor94d96292011-01-19 20:34:17 +00002257 case VisitorJob::SizeOfPackExprPartsKind: {
2258 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2259 NamedDecl *Pack = E->getPack();
2260 if (isa<TemplateTypeParmDecl>(Pack)) {
2261 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2262 E->getPackLoc(), TU)))
2263 return true;
2264
2265 continue;
2266 }
2267
2268 if (isa<TemplateTemplateParmDecl>(Pack)) {
2269 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2270 E->getPackLoc(), TU)))
2271 return true;
2272
2273 continue;
2274 }
2275
2276 // Non-type template parameter packs and function parameter packs are
2277 // treated like DeclRefExpr cursors.
2278 continue;
2279 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002280 }
2281 }
2282 return false;
2283}
2284
Ted Kremenekcdba6592010-11-18 00:42:18 +00002285bool CursorVisitor::Visit(Stmt *S) {
Ted Kremenekd1ded662010-11-15 23:31:32 +00002286 VisitorWorkList *WL = 0;
2287 if (!WorkListFreeList.empty()) {
2288 WL = WorkListFreeList.back();
2289 WL->clear();
2290 WorkListFreeList.pop_back();
2291 }
2292 else {
2293 WL = new VisitorWorkList();
2294 WorkListCache.push_back(WL);
2295 }
2296 EnqueueWorkList(*WL, S);
2297 bool result = RunVisitorWorkList(*WL);
2298 WorkListFreeList.push_back(WL);
2299 return result;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002300}
2301
2302//===----------------------------------------------------------------------===//
2303// Misc. API hooks.
2304//===----------------------------------------------------------------------===//
2305
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002306static llvm::sys::Mutex EnableMultithreadingMutex;
2307static bool EnabledMultithreading;
2308
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002309extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002310CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2311 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002312 // Disable pretty stack trace functionality, which will otherwise be a very
2313 // poor citizen of the world and set up all sorts of signal handlers.
2314 llvm::DisablePrettyStackTrace = true;
2315
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002316 // We use crash recovery to make some of our APIs more reliable, implicitly
2317 // enable it.
2318 llvm::CrashRecoveryContext::Enable();
2319
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002320 // Enable support for multithreading in LLVM.
2321 {
2322 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2323 if (!EnabledMultithreading) {
2324 llvm::llvm_start_multithreaded();
2325 EnabledMultithreading = true;
2326 }
2327 }
2328
Douglas Gregora030b7c2010-01-22 20:35:53 +00002329 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002330 if (excludeDeclarationsFromPCH)
2331 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002332 if (displayDiagnostics)
2333 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002334 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002335}
2336
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002337void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002338 if (CIdx)
2339 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002340}
2341
Ted Kremenekd2427dd2011-03-18 23:05:39 +00002342void clang_toggleCrashRecovery(unsigned isEnabled) {
2343 if (isEnabled)
2344 llvm::CrashRecoveryContext::Enable();
2345 else
2346 llvm::CrashRecoveryContext::Disable();
2347}
2348
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002349CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002350 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002351 if (!CIdx)
2352 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002353
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002354 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002355 FileSystemOptions FileSystemOpts;
2356 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002357
Douglas Gregor28019772010-04-05 23:52:57 +00002358 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremeneka60ed472010-11-16 08:15:36 +00002359 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002360 CXXIdx->getOnlyLocalDecls(),
2361 0, 0, true);
Ted Kremeneka60ed472010-11-16 08:15:36 +00002362 return MakeCXTranslationUnit(TU);
Steve Naroff600866c2009-08-27 19:51:58 +00002363}
2364
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002365unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002366 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002367 CXTranslationUnit_CacheCompletionResults |
2368 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002369}
2370
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002371CXTranslationUnit
2372clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2373 const char *source_filename,
2374 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002375 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002376 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002377 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor5a430212010-07-21 18:52:53 +00002378 return clang_parseTranslationUnit(CIdx, source_filename,
2379 command_line_args, num_command_line_args,
2380 unsaved_files, num_unsaved_files,
2381 CXTranslationUnit_DetailedPreprocessingRecord);
2382}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002383
2384struct ParseTranslationUnitInfo {
2385 CXIndex CIdx;
2386 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002387 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002388 int num_command_line_args;
2389 struct CXUnsavedFile *unsaved_files;
2390 unsigned num_unsaved_files;
2391 unsigned options;
2392 CXTranslationUnit result;
2393};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002394static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002395 ParseTranslationUnitInfo *PTUI =
2396 static_cast<ParseTranslationUnitInfo*>(UserData);
2397 CXIndex CIdx = PTUI->CIdx;
2398 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002399 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002400 int num_command_line_args = PTUI->num_command_line_args;
2401 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2402 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2403 unsigned options = PTUI->options;
2404 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002405
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002406 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002407 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002408
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002409 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2410
Douglas Gregor44c181a2010-07-23 00:33:23 +00002411 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002412 bool CompleteTranslationUnit
2413 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002414 bool CacheCodeCompetionResults
2415 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002416 bool CXXPrecompilePreamble
2417 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2418 bool CXXChainedPCH
2419 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002420
Douglas Gregor5352ac02010-01-28 00:27:43 +00002421 // Configure the diagnostics.
2422 DiagnosticOptions DiagOpts;
Ted Kremenek25a11e12011-03-22 01:15:24 +00002423 llvm::IntrusiveRefCntPtr<Diagnostic>
2424 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2425 command_line_args));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002426
Ted Kremenek25a11e12011-03-22 01:15:24 +00002427 // Recover resources if we crash before exiting this function.
2428 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2429 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2430 DiagCleanup(Diags.getPtr());
2431
2432 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2433 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2434
2435 // Recover resources if we crash before exiting this function.
2436 llvm::CrashRecoveryContextCleanupRegistrar<
2437 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2438
Douglas Gregor4db64a42010-01-23 00:14:00 +00002439 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002440 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002441 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002442 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002443 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2444 Buffer));
Douglas Gregor4db64a42010-01-23 00:14:00 +00002445 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002446
Ted Kremenek25a11e12011-03-22 01:15:24 +00002447 llvm::OwningPtr<std::vector<const char *> >
2448 Args(new std::vector<const char*>());
2449
2450 // Recover resources if we crash before exiting this method.
2451 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2452 ArgsCleanup(Args.get());
2453
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002454 // Since the Clang C library is primarily used by batch tools dealing with
2455 // (often very broken) source code, where spell-checking can have a
2456 // significant negative impact on performance (particularly when
2457 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002458 // Only do this if we haven't found a spell-checking-related argument.
2459 bool FoundSpellCheckingArgument = false;
2460 for (int I = 0; I != num_command_line_args; ++I) {
2461 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2462 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2463 FoundSpellCheckingArgument = true;
2464 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002465 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002466 }
2467 if (!FoundSpellCheckingArgument)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002468 Args->push_back("-fno-spell-checking");
Douglas Gregorb10daed2010-10-11 16:52:23 +00002469
Ted Kremenek25a11e12011-03-22 01:15:24 +00002470 Args->insert(Args->end(), command_line_args,
2471 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002472
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002473 // The 'source_filename' argument is optional. If the caller does not
2474 // specify it then it is assumed that the source file is specified
2475 // in the actual argument list.
2476 // Put the source file after command_line_args otherwise if '-x' flag is
2477 // present it will be unused.
2478 if (source_filename)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002479 Args->push_back(source_filename);
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002480
Douglas Gregor44c181a2010-07-23 00:33:23 +00002481 // Do we need the detailed preprocessing record?
2482 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek25a11e12011-03-22 01:15:24 +00002483 Args->push_back("-Xclang");
2484 Args->push_back("-detailed-preprocessing-record");
Douglas Gregor44c181a2010-07-23 00:33:23 +00002485 }
2486
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002487 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002488 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek4ee99262011-03-22 20:16:19 +00002489 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2490 /* vector::data() not portable */,
2491 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002492 Diags,
2493 CXXIdx->getClangResourcesPath(),
2494 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002495 /*CaptureDiagnostics=*/true,
Ted Kremenek4ee99262011-03-22 20:16:19 +00002496 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek25a11e12011-03-22 01:15:24 +00002497 RemappedFiles->size(),
Argyrios Kyrtzidis299a4a92011-03-08 23:35:24 +00002498 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002499 PrecompilePreamble,
2500 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002501 CacheCodeCompetionResults,
2502 CXXPrecompilePreamble,
2503 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002504
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002505 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002506 // Make sure to check that 'Unit' is non-NULL.
2507 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2508 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2509 DEnd = Unit->stored_diag_end();
2510 D != DEnd; ++D) {
2511 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2512 CXString Msg = clang_formatDiagnostic(&Diag,
2513 clang_defaultDiagnosticDisplayOptions());
2514 fprintf(stderr, "%s\n", clang_getCString(Msg));
2515 clang_disposeString(Msg);
2516 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002517#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002518 // On Windows, force a flush, since there may be multiple copies of
2519 // stderr and stdout in the file system, all with different buffers
2520 // but writing to the same device.
2521 fflush(stderr);
2522#endif
2523 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002524 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002525
Ted Kremeneka60ed472010-11-16 08:15:36 +00002526 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002527}
2528CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2529 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002530 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002531 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002532 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002533 unsigned num_unsaved_files,
2534 unsigned options) {
2535 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002536 num_command_line_args, unsaved_files,
2537 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002538 llvm::CrashRecoveryContext CRC;
2539
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002540 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002541 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2542 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2543 fprintf(stderr, " 'command_line_args' : [");
2544 for (int i = 0; i != num_command_line_args; ++i) {
2545 if (i)
2546 fprintf(stderr, ", ");
2547 fprintf(stderr, "'%s'", command_line_args[i]);
2548 }
2549 fprintf(stderr, "],\n");
2550 fprintf(stderr, " 'unsaved_files' : [");
2551 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2552 if (i)
2553 fprintf(stderr, ", ");
2554 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2555 unsaved_files[i].Length);
2556 }
2557 fprintf(stderr, "],\n");
2558 fprintf(stderr, " 'options' : %d,\n", options);
2559 fprintf(stderr, "}\n");
2560
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002561 return 0;
2562 }
2563
2564 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002565}
2566
Douglas Gregor19998442010-08-13 15:35:05 +00002567unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2568 return CXSaveTranslationUnit_None;
2569}
2570
2571int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2572 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002573 if (!TU)
2574 return 1;
2575
Ted Kremeneka60ed472010-11-16 08:15:36 +00002576 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002577}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002578
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002579void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002580 if (CTUnit) {
2581 // If the translation unit has been marked as unsafe to free, just discard
2582 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002583 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002584 return;
2585
Ted Kremeneka60ed472010-11-16 08:15:36 +00002586 delete static_cast<ASTUnit *>(CTUnit->TUData);
2587 disposeCXStringPool(CTUnit->StringPool);
2588 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002589 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002590}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002591
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002592unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2593 return CXReparse_None;
2594}
2595
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002596struct ReparseTranslationUnitInfo {
2597 CXTranslationUnit TU;
2598 unsigned num_unsaved_files;
2599 struct CXUnsavedFile *unsaved_files;
2600 unsigned options;
2601 int result;
2602};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002603
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002604static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002605 ReparseTranslationUnitInfo *RTUI =
2606 static_cast<ReparseTranslationUnitInfo*>(UserData);
2607 CXTranslationUnit TU = RTUI->TU;
2608 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2609 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2610 unsigned options = RTUI->options;
2611 (void) options;
2612 RTUI->result = 1;
2613
Douglas Gregorabc563f2010-07-19 21:46:24 +00002614 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002615 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002616
Ted Kremeneka60ed472010-11-16 08:15:36 +00002617 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002618 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002619
Ted Kremenek25a11e12011-03-22 01:15:24 +00002620 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2621 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2622
2623 // Recover resources if we crash before exiting this function.
2624 llvm::CrashRecoveryContextCleanupRegistrar<
2625 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2626
Douglas Gregorabc563f2010-07-19 21:46:24 +00002627 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2628 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2629 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002630 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002631 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2632 Buffer));
Douglas Gregorabc563f2010-07-19 21:46:24 +00002633 }
2634
Ted Kremenek4ee99262011-03-22 20:16:19 +00002635 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2636 RemappedFiles->size()))
Douglas Gregor593b0c12010-09-23 18:47:53 +00002637 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002638}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002639
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002640int clang_reparseTranslationUnit(CXTranslationUnit TU,
2641 unsigned num_unsaved_files,
2642 struct CXUnsavedFile *unsaved_files,
2643 unsigned options) {
2644 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2645 options, 0 };
2646 llvm::CrashRecoveryContext CRC;
2647
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002648 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002649 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002650 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002651 return 1;
2652 }
2653
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002654
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002655 return RTUI.result;
2656}
2657
Douglas Gregordf95a132010-08-09 20:45:32 +00002658
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002659CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002660 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002661 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002662
Ted Kremeneka60ed472010-11-16 08:15:36 +00002663 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002664 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002665}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002666
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002667CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002668 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002669 return Result;
2670}
2671
Ted Kremenekfb480492010-01-13 21:46:36 +00002672} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002673
Ted Kremenekfb480492010-01-13 21:46:36 +00002674//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002675// CXSourceLocation and CXSourceRange Operations.
2676//===----------------------------------------------------------------------===//
2677
Douglas Gregorb9790342010-01-22 21:44:22 +00002678extern "C" {
2679CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002680 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002681 return Result;
2682}
2683
2684unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002685 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2686 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2687 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002688}
2689
2690CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2691 CXFile file,
2692 unsigned line,
2693 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002694 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002695 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002696
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002697 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002698 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002699 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002700 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002701 = CXXUnit->getSourceManager().getLocation(File, line, column);
2702 if (SLoc.isInvalid()) {
2703 if (Logging)
2704 llvm::errs() << "clang_getLocation(\"" << File->getName()
2705 << "\", " << line << ", " << column << ") = invalid\n";
2706 return clang_getNullLocation();
2707 }
2708
2709 if (Logging)
2710 llvm::errs() << "clang_getLocation(\"" << File->getName()
2711 << "\", " << line << ", " << column << ") = "
2712 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002713
2714 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2715}
2716
2717CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2718 CXFile file,
2719 unsigned offset) {
2720 if (!tu || !file)
2721 return clang_getNullLocation();
2722
Ted Kremeneka60ed472010-11-16 08:15:36 +00002723 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002724 SourceLocation Start
2725 = CXXUnit->getSourceManager().getLocation(
2726 static_cast<const FileEntry *>(file),
2727 1, 1);
2728 if (Start.isInvalid()) return clang_getNullLocation();
2729
2730 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2731
2732 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002733
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002734 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002735}
2736
Douglas Gregor5352ac02010-01-28 00:27:43 +00002737CXSourceRange clang_getNullRange() {
2738 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2739 return Result;
2740}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002741
Douglas Gregor5352ac02010-01-28 00:27:43 +00002742CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2743 if (begin.ptr_data[0] != end.ptr_data[0] ||
2744 begin.ptr_data[1] != end.ptr_data[1])
2745 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002746
2747 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002748 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002749 return Result;
2750}
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002751} // end: extern "C"
Douglas Gregorb9790342010-01-22 21:44:22 +00002752
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002753static void createNullLocation(CXFile *file, unsigned *line,
2754 unsigned *column, unsigned *offset) {
2755 if (file)
2756 *file = 0;
2757 if (line)
2758 *line = 0;
2759 if (column)
2760 *column = 0;
2761 if (offset)
2762 *offset = 0;
2763 return;
2764}
2765
2766extern "C" {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002767void clang_getInstantiationLocation(CXSourceLocation location,
2768 CXFile *file,
2769 unsigned *line,
2770 unsigned *column,
2771 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002772 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2773
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002774 if (!location.ptr_data[0] || Loc.isInvalid()) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002775 createNullLocation(file, line, column, offset);
Douglas Gregor46766dc2010-01-26 19:19:08 +00002776 return;
2777 }
2778
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002779 const SourceManager &SM =
2780 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002781 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002782
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002783 // Check that the FileID is invalid on the instantiation location.
2784 // This can manifest in invalid code.
2785 FileID fileID = SM.getFileID(InstLoc);
Douglas Gregore23ac652011-04-20 00:21:03 +00002786 bool Invalid = false;
2787 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
2788 if (!sloc.isFile() || Invalid) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002789 createNullLocation(file, line, column, offset);
2790 return;
2791 }
2792
Douglas Gregor1db19de2010-01-19 21:36:55 +00002793 if (file)
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002794 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002795 if (line)
2796 *line = SM.getInstantiationLineNumber(InstLoc);
2797 if (column)
2798 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002799 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002800 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002801}
2802
Douglas Gregora9b06d42010-11-09 06:24:54 +00002803void clang_getSpellingLocation(CXSourceLocation location,
2804 CXFile *file,
2805 unsigned *line,
2806 unsigned *column,
2807 unsigned *offset) {
2808 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2809
2810 if (!location.ptr_data[0] || Loc.isInvalid()) {
2811 if (file)
2812 *file = 0;
2813 if (line)
2814 *line = 0;
2815 if (column)
2816 *column = 0;
2817 if (offset)
2818 *offset = 0;
2819 return;
2820 }
2821
2822 const SourceManager &SM =
2823 *static_cast<const SourceManager*>(location.ptr_data[0]);
2824 SourceLocation SpellLoc = Loc;
2825 if (SpellLoc.isMacroID()) {
2826 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2827 if (SimpleSpellingLoc.isFileID() &&
2828 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2829 SpellLoc = SimpleSpellingLoc;
2830 else
2831 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2832 }
2833
2834 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2835 FileID FID = LocInfo.first;
2836 unsigned FileOffset = LocInfo.second;
2837
2838 if (file)
2839 *file = (void *)SM.getFileEntryForID(FID);
2840 if (line)
2841 *line = SM.getLineNumber(FID, FileOffset);
2842 if (column)
2843 *column = SM.getColumnNumber(FID, FileOffset);
2844 if (offset)
2845 *offset = FileOffset;
2846}
2847
Douglas Gregor1db19de2010-01-19 21:36:55 +00002848CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002849 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002850 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002851 return Result;
2852}
2853
2854CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002855 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002856 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002857 return Result;
2858}
2859
Douglas Gregorb9790342010-01-22 21:44:22 +00002860} // end: extern "C"
2861
Douglas Gregor1db19de2010-01-19 21:36:55 +00002862//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002863// CXFile Operations.
2864//===----------------------------------------------------------------------===//
2865
2866extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002867CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002868 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002869 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002870
Steve Naroff88145032009-10-27 14:35:18 +00002871 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002872 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002873}
2874
2875time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002876 if (!SFile)
2877 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002878
Steve Naroff88145032009-10-27 14:35:18 +00002879 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2880 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002881}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002882
Douglas Gregorb9790342010-01-22 21:44:22 +00002883CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2884 if (!tu)
2885 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002886
Ted Kremeneka60ed472010-11-16 08:15:36 +00002887 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002888
Douglas Gregorb9790342010-01-22 21:44:22 +00002889 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002890 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002891}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002892
Ted Kremenekfb480492010-01-13 21:46:36 +00002893} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002894
Ted Kremenekfb480492010-01-13 21:46:36 +00002895//===----------------------------------------------------------------------===//
2896// CXCursor Operations.
2897//===----------------------------------------------------------------------===//
2898
Ted Kremenekfb480492010-01-13 21:46:36 +00002899static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002900 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2901 return getDeclFromExpr(CE->getSubExpr());
2902
Ted Kremenekfb480492010-01-13 21:46:36 +00002903 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2904 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002905 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2906 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002907 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2908 return ME->getMemberDecl();
2909 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2910 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002911 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002912 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002913
Ted Kremenekfb480492010-01-13 21:46:36 +00002914 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2915 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002916 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2917 if (!CE->isElidable())
2918 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002919 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2920 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002921
Douglas Gregordb1314e2010-10-01 21:11:22 +00002922 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2923 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002924 if (SubstNonTypeTemplateParmPackExpr *NTTP
2925 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2926 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002927 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2928 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2929 isa<ParmVarDecl>(SizeOfPack->getPack()))
2930 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002931
Ted Kremenekfb480492010-01-13 21:46:36 +00002932 return 0;
2933}
2934
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002935static SourceLocation getLocationFromExpr(Expr *E) {
2936 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2937 return /*FIXME:*/Msg->getLeftLoc();
2938 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2939 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002940 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2941 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002942 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2943 return Member->getMemberLoc();
2944 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2945 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002946 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2947 return SizeOfPack->getPackLoc();
2948
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002949 return E->getLocStart();
2950}
2951
Ted Kremenekfb480492010-01-13 21:46:36 +00002952extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002953
2954unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002955 CXCursorVisitor visitor,
2956 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002957 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00002958 getCursorASTUnit(parent)->getMaxPCHLevel(),
2959 false);
Douglas Gregorb1373d02010-01-20 20:59:29 +00002960 return CursorVis.VisitChildren(parent);
2961}
2962
David Chisnall3387c652010-11-03 14:12:26 +00002963#ifndef __has_feature
2964#define __has_feature(x) 0
2965#endif
2966#if __has_feature(blocks)
2967typedef enum CXChildVisitResult
2968 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2969
2970static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2971 CXClientData client_data) {
2972 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2973 return block(cursor, parent);
2974}
2975#else
2976// If we are compiled with a compiler that doesn't have native blocks support,
2977// define and call the block manually, so the
2978typedef struct _CXChildVisitResult
2979{
2980 void *isa;
2981 int flags;
2982 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002983 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2984 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002985} *CXCursorVisitorBlock;
2986
2987static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2988 CXClientData client_data) {
2989 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2990 return block->invoke(block, cursor, parent);
2991}
2992#endif
2993
2994
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002995unsigned clang_visitChildrenWithBlock(CXCursor parent,
2996 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002997 return clang_visitChildren(parent, visitWithBlock, block);
2998}
2999
Douglas Gregor78205d42010-01-20 21:45:58 +00003000static CXString getDeclSpelling(Decl *D) {
3001 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003002 if (!ND) {
3003 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3004 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3005 return createCXString(Property->getIdentifier()->getName());
3006
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003007 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00003008 }
3009
Douglas Gregor78205d42010-01-20 21:45:58 +00003010 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003011 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003012
Douglas Gregor78205d42010-01-20 21:45:58 +00003013 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
3014 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3015 // and returns different names. NamedDecl returns the class name and
3016 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003017 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003018
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003019 if (isa<UsingDirectiveDecl>(D))
3020 return createCXString("");
3021
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00003022 llvm::SmallString<1024> S;
3023 llvm::raw_svector_ostream os(S);
3024 ND->printName(os);
3025
3026 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00003027}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003028
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003029CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003030 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003031 return clang_getTranslationUnitSpelling(
3032 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003033
Steve Narofff334b4e2009-09-02 18:26:48 +00003034 if (clang_isReference(C.kind)) {
3035 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00003036 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00003037 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003038 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003039 }
3040 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00003041 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003042 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003043 }
3044 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00003045 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00003046 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003047 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003048 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00003049 case CXCursor_CXXBaseSpecifier: {
3050 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3051 return createCXString(B->getType().getAsString());
3052 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003053 case CXCursor_TypeRef: {
3054 TypeDecl *Type = getCursorTypeRef(C).first;
3055 assert(Type && "Missing type decl");
3056
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003057 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3058 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003059 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003060 case CXCursor_TemplateRef: {
3061 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00003062 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003063
3064 return createCXString(Template->getNameAsString());
3065 }
Douglas Gregor69319002010-08-31 23:48:11 +00003066
3067 case CXCursor_NamespaceRef: {
3068 NamedDecl *NS = getCursorNamespaceRef(C).first;
3069 assert(NS && "Missing namespace decl");
3070
3071 return createCXString(NS->getNameAsString());
3072 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003073
Douglas Gregora67e03f2010-09-09 21:42:20 +00003074 case CXCursor_MemberRef: {
3075 FieldDecl *Field = getCursorMemberRef(C).first;
3076 assert(Field && "Missing member decl");
3077
3078 return createCXString(Field->getNameAsString());
3079 }
3080
Douglas Gregor36897b02010-09-10 00:22:18 +00003081 case CXCursor_LabelRef: {
3082 LabelStmt *Label = getCursorLabelRef(C).first;
3083 assert(Label && "Missing label");
3084
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003085 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003086 }
3087
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003088 case CXCursor_OverloadedDeclRef: {
3089 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3090 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3091 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3092 return createCXString(ND->getNameAsString());
3093 return createCXString("");
3094 }
3095 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3096 return createCXString(E->getName().getAsString());
3097 OverloadedTemplateStorage *Ovl
3098 = Storage.get<OverloadedTemplateStorage*>();
3099 if (Ovl->size() == 0)
3100 return createCXString("");
3101 return createCXString((*Ovl->begin())->getNameAsString());
3102 }
3103
Daniel Dunbaracca7252009-11-30 20:42:49 +00003104 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003105 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003106 }
3107 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003108
3109 if (clang_isExpression(C.kind)) {
3110 Decl *D = getDeclFromExpr(getCursorExpr(C));
3111 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003112 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003113 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003114 }
3115
Douglas Gregor36897b02010-09-10 00:22:18 +00003116 if (clang_isStatement(C.kind)) {
3117 Stmt *S = getCursorStmt(C);
3118 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003119 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003120
3121 return createCXString("");
3122 }
3123
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003124 if (C.kind == CXCursor_MacroInstantiation)
3125 return createCXString(getCursorMacroInstantiation(C)->getName()
3126 ->getNameStart());
3127
Douglas Gregor572feb22010-03-18 18:04:21 +00003128 if (C.kind == CXCursor_MacroDefinition)
3129 return createCXString(getCursorMacroDefinition(C)->getName()
3130 ->getNameStart());
3131
Douglas Gregorecdcb882010-10-20 22:00:55 +00003132 if (C.kind == CXCursor_InclusionDirective)
3133 return createCXString(getCursorInclusionDirective(C)->getFileName());
3134
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003135 if (clang_isDeclaration(C.kind))
3136 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003137
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003138 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003139}
3140
Douglas Gregor358559d2010-10-02 22:49:11 +00003141CXString clang_getCursorDisplayName(CXCursor C) {
3142 if (!clang_isDeclaration(C.kind))
3143 return clang_getCursorSpelling(C);
3144
3145 Decl *D = getCursorDecl(C);
3146 if (!D)
3147 return createCXString("");
3148
3149 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3150 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3151 D = FunTmpl->getTemplatedDecl();
3152
3153 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3154 llvm::SmallString<64> Str;
3155 llvm::raw_svector_ostream OS(Str);
3156 OS << Function->getNameAsString();
3157 if (Function->getPrimaryTemplate())
3158 OS << "<>";
3159 OS << "(";
3160 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3161 if (I)
3162 OS << ", ";
3163 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3164 }
3165
3166 if (Function->isVariadic()) {
3167 if (Function->getNumParams())
3168 OS << ", ";
3169 OS << "...";
3170 }
3171 OS << ")";
3172 return createCXString(OS.str());
3173 }
3174
3175 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3176 llvm::SmallString<64> Str;
3177 llvm::raw_svector_ostream OS(Str);
3178 OS << ClassTemplate->getNameAsString();
3179 OS << "<";
3180 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3181 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3182 if (I)
3183 OS << ", ";
3184
3185 NamedDecl *Param = Params->getParam(I);
3186 if (Param->getIdentifier()) {
3187 OS << Param->getIdentifier()->getName();
3188 continue;
3189 }
3190
3191 // There is no parameter name, which makes this tricky. Try to come up
3192 // with something useful that isn't too long.
3193 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3194 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3195 else if (NonTypeTemplateParmDecl *NTTP
3196 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3197 OS << NTTP->getType().getAsString(Policy);
3198 else
3199 OS << "template<...> class";
3200 }
3201
3202 OS << ">";
3203 return createCXString(OS.str());
3204 }
3205
3206 if (ClassTemplateSpecializationDecl *ClassSpec
3207 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3208 // If the type was explicitly written, use that.
3209 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3210 return createCXString(TSInfo->getType().getAsString(Policy));
3211
3212 llvm::SmallString<64> Str;
3213 llvm::raw_svector_ostream OS(Str);
3214 OS << ClassSpec->getNameAsString();
3215 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003216 ClassSpec->getTemplateArgs().data(),
3217 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003218 Policy);
3219 return createCXString(OS.str());
3220 }
3221
3222 return clang_getCursorSpelling(C);
3223}
3224
Ted Kremeneke68fff62010-02-17 00:41:32 +00003225CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003226 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003227 case CXCursor_FunctionDecl:
3228 return createCXString("FunctionDecl");
3229 case CXCursor_TypedefDecl:
3230 return createCXString("TypedefDecl");
3231 case CXCursor_EnumDecl:
3232 return createCXString("EnumDecl");
3233 case CXCursor_EnumConstantDecl:
3234 return createCXString("EnumConstantDecl");
3235 case CXCursor_StructDecl:
3236 return createCXString("StructDecl");
3237 case CXCursor_UnionDecl:
3238 return createCXString("UnionDecl");
3239 case CXCursor_ClassDecl:
3240 return createCXString("ClassDecl");
3241 case CXCursor_FieldDecl:
3242 return createCXString("FieldDecl");
3243 case CXCursor_VarDecl:
3244 return createCXString("VarDecl");
3245 case CXCursor_ParmDecl:
3246 return createCXString("ParmDecl");
3247 case CXCursor_ObjCInterfaceDecl:
3248 return createCXString("ObjCInterfaceDecl");
3249 case CXCursor_ObjCCategoryDecl:
3250 return createCXString("ObjCCategoryDecl");
3251 case CXCursor_ObjCProtocolDecl:
3252 return createCXString("ObjCProtocolDecl");
3253 case CXCursor_ObjCPropertyDecl:
3254 return createCXString("ObjCPropertyDecl");
3255 case CXCursor_ObjCIvarDecl:
3256 return createCXString("ObjCIvarDecl");
3257 case CXCursor_ObjCInstanceMethodDecl:
3258 return createCXString("ObjCInstanceMethodDecl");
3259 case CXCursor_ObjCClassMethodDecl:
3260 return createCXString("ObjCClassMethodDecl");
3261 case CXCursor_ObjCImplementationDecl:
3262 return createCXString("ObjCImplementationDecl");
3263 case CXCursor_ObjCCategoryImplDecl:
3264 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003265 case CXCursor_CXXMethod:
3266 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003267 case CXCursor_UnexposedDecl:
3268 return createCXString("UnexposedDecl");
3269 case CXCursor_ObjCSuperClassRef:
3270 return createCXString("ObjCSuperClassRef");
3271 case CXCursor_ObjCProtocolRef:
3272 return createCXString("ObjCProtocolRef");
3273 case CXCursor_ObjCClassRef:
3274 return createCXString("ObjCClassRef");
3275 case CXCursor_TypeRef:
3276 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003277 case CXCursor_TemplateRef:
3278 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003279 case CXCursor_NamespaceRef:
3280 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003281 case CXCursor_MemberRef:
3282 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003283 case CXCursor_LabelRef:
3284 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003285 case CXCursor_OverloadedDeclRef:
3286 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003287 case CXCursor_UnexposedExpr:
3288 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003289 case CXCursor_BlockExpr:
3290 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003291 case CXCursor_DeclRefExpr:
3292 return createCXString("DeclRefExpr");
3293 case CXCursor_MemberRefExpr:
3294 return createCXString("MemberRefExpr");
3295 case CXCursor_CallExpr:
3296 return createCXString("CallExpr");
3297 case CXCursor_ObjCMessageExpr:
3298 return createCXString("ObjCMessageExpr");
3299 case CXCursor_UnexposedStmt:
3300 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003301 case CXCursor_LabelStmt:
3302 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003303 case CXCursor_InvalidFile:
3304 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003305 case CXCursor_InvalidCode:
3306 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003307 case CXCursor_NoDeclFound:
3308 return createCXString("NoDeclFound");
3309 case CXCursor_NotImplemented:
3310 return createCXString("NotImplemented");
3311 case CXCursor_TranslationUnit:
3312 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003313 case CXCursor_UnexposedAttr:
3314 return createCXString("UnexposedAttr");
3315 case CXCursor_IBActionAttr:
3316 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003317 case CXCursor_IBOutletAttr:
3318 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003319 case CXCursor_IBOutletCollectionAttr:
3320 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003321 case CXCursor_PreprocessingDirective:
3322 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003323 case CXCursor_MacroDefinition:
3324 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003325 case CXCursor_MacroInstantiation:
3326 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003327 case CXCursor_InclusionDirective:
3328 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003329 case CXCursor_Namespace:
3330 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003331 case CXCursor_LinkageSpec:
3332 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003333 case CXCursor_CXXBaseSpecifier:
3334 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003335 case CXCursor_Constructor:
3336 return createCXString("CXXConstructor");
3337 case CXCursor_Destructor:
3338 return createCXString("CXXDestructor");
3339 case CXCursor_ConversionFunction:
3340 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003341 case CXCursor_TemplateTypeParameter:
3342 return createCXString("TemplateTypeParameter");
3343 case CXCursor_NonTypeTemplateParameter:
3344 return createCXString("NonTypeTemplateParameter");
3345 case CXCursor_TemplateTemplateParameter:
3346 return createCXString("TemplateTemplateParameter");
3347 case CXCursor_FunctionTemplate:
3348 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003349 case CXCursor_ClassTemplate:
3350 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003351 case CXCursor_ClassTemplatePartialSpecialization:
3352 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003353 case CXCursor_NamespaceAlias:
3354 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003355 case CXCursor_UsingDirective:
3356 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003357 case CXCursor_UsingDeclaration:
3358 return createCXString("UsingDeclaration");
Richard Smith162e1c12011-04-15 14:24:37 +00003359 case CXCursor_TypeAliasDecl:
3360 return createCXString("TypeAliasDecl");
Steve Naroff89922f82009-08-31 00:59:03 +00003361 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003362
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003363 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003364 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003365}
Steve Naroff89922f82009-08-31 00:59:03 +00003366
Ted Kremeneke68fff62010-02-17 00:41:32 +00003367enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3368 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003369 CXClientData client_data) {
3370 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003371
3372 // If our current best cursor is the construction of a temporary object,
3373 // don't replace that cursor with a type reference, because we want
3374 // clang_getCursor() to point at the constructor.
3375 if (clang_isExpression(BestCursor->kind) &&
3376 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3377 cursor.kind == CXCursor_TypeRef)
3378 return CXChildVisit_Recurse;
3379
Douglas Gregor85fe1562010-12-10 07:23:11 +00003380 // Don't override a preprocessing cursor with another preprocessing
3381 // cursor; we want the outermost preprocessing cursor.
3382 if (clang_isPreprocessing(cursor.kind) &&
3383 clang_isPreprocessing(BestCursor->kind))
3384 return CXChildVisit_Recurse;
3385
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003386 *BestCursor = cursor;
3387 return CXChildVisit_Recurse;
3388}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003389
Douglas Gregorb9790342010-01-22 21:44:22 +00003390CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3391 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003392 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003393
Ted Kremeneka60ed472010-11-16 08:15:36 +00003394 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003395 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3396
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003397 // Translate the given source location to make it point at the beginning of
3398 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003399 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003400
3401 // Guard against an invalid SourceLocation, or we may assert in one
3402 // of the following calls.
3403 if (SLoc.isInvalid())
3404 return clang_getNullCursor();
3405
Douglas Gregor40749ee2010-11-03 00:35:38 +00003406 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003407 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3408 CXXUnit->getASTContext().getLangOptions());
3409
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003410 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3411 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003412 // FIXME: Would be great to have a "hint" cursor, then walk from that
3413 // hint cursor upward until we find a cursor whose source range encloses
3414 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003415 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3416 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00003417 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003418 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003419 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003420
3421 if (Logging) {
3422 CXFile SearchFile;
3423 unsigned SearchLine, SearchColumn;
3424 CXFile ResultFile;
3425 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003426 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3427 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003428 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3429
3430 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3431 0);
3432 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3433 &ResultColumn, 0);
3434 SearchFileName = clang_getFileName(SearchFile);
3435 ResultFileName = clang_getFileName(ResultFile);
3436 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003437 USR = clang_getCursorUSR(Result);
3438 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003439 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3440 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003441 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3442 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003443 clang_disposeString(SearchFileName);
3444 clang_disposeString(ResultFileName);
3445 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003446 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003447
3448 CXCursor Definition = clang_getCursorDefinition(Result);
3449 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3450 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3451 CXString DefinitionKindSpelling
3452 = clang_getCursorKindSpelling(Definition.kind);
3453 CXFile DefinitionFile;
3454 unsigned DefinitionLine, DefinitionColumn;
3455 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3456 &DefinitionLine, &DefinitionColumn, 0);
3457 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3458 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3459 clang_getCString(DefinitionKindSpelling),
3460 clang_getCString(DefinitionFileName),
3461 DefinitionLine, DefinitionColumn);
3462 clang_disposeString(DefinitionFileName);
3463 clang_disposeString(DefinitionKindSpelling);
3464 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003465 }
3466
Ted Kremeneke68fff62010-02-17 00:41:32 +00003467 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003468}
3469
Ted Kremenek73885552009-11-17 19:28:59 +00003470CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003471 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003472}
3473
3474unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003475 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003476}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003477
Douglas Gregor9ce55842010-11-20 00:09:34 +00003478unsigned clang_hashCursor(CXCursor C) {
3479 unsigned Index = 0;
3480 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3481 Index = 1;
3482
3483 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3484 std::make_pair(C.kind, C.data[Index]));
3485}
3486
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003487unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003488 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3489}
3490
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003491unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003492 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3493}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003494
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003495unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003496 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3497}
3498
Douglas Gregor97b98722010-01-19 23:20:36 +00003499unsigned clang_isExpression(enum CXCursorKind K) {
3500 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3501}
3502
3503unsigned clang_isStatement(enum CXCursorKind K) {
3504 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3505}
3506
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003507unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3508 return K == CXCursor_TranslationUnit;
3509}
3510
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003511unsigned clang_isPreprocessing(enum CXCursorKind K) {
3512 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3513}
3514
Ted Kremenekad6eff62010-03-08 21:17:29 +00003515unsigned clang_isUnexposed(enum CXCursorKind K) {
3516 switch (K) {
3517 case CXCursor_UnexposedDecl:
3518 case CXCursor_UnexposedExpr:
3519 case CXCursor_UnexposedStmt:
3520 case CXCursor_UnexposedAttr:
3521 return true;
3522 default:
3523 return false;
3524 }
3525}
3526
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003527CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003528 return C.kind;
3529}
3530
Douglas Gregor98258af2010-01-18 22:46:11 +00003531CXSourceLocation clang_getCursorLocation(CXCursor C) {
3532 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003533 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003534 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003535 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3536 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003537 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003538 }
3539
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003540 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003541 std::pair<ObjCProtocolDecl *, SourceLocation> P
3542 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003543 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003544 }
3545
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003546 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003547 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3548 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003549 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003550 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003551
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003552 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003553 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003554 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003555 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003556
3557 case CXCursor_TemplateRef: {
3558 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3559 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3560 }
3561
Douglas Gregor69319002010-08-31 23:48:11 +00003562 case CXCursor_NamespaceRef: {
3563 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3564 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3565 }
3566
Douglas Gregora67e03f2010-09-09 21:42:20 +00003567 case CXCursor_MemberRef: {
3568 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3569 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3570 }
3571
Ted Kremenek3064ef92010-08-27 21:34:58 +00003572 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003573 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3574 if (!BaseSpec)
3575 return clang_getNullLocation();
3576
3577 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3578 return cxloc::translateSourceLocation(getCursorContext(C),
3579 TSInfo->getTypeLoc().getBeginLoc());
3580
3581 return cxloc::translateSourceLocation(getCursorContext(C),
3582 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003583 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003584
Douglas Gregor36897b02010-09-10 00:22:18 +00003585 case CXCursor_LabelRef: {
3586 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3587 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3588 }
3589
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003590 case CXCursor_OverloadedDeclRef:
3591 return cxloc::translateSourceLocation(getCursorContext(C),
3592 getCursorOverloadedDeclRef(C).second);
3593
Douglas Gregorf46034a2010-01-18 23:41:10 +00003594 default:
3595 // FIXME: Need a way to enumerate all non-reference cases.
3596 llvm_unreachable("Missed a reference kind");
3597 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003598 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003599
3600 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003601 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003602 getLocationFromExpr(getCursorExpr(C)));
3603
Douglas Gregor36897b02010-09-10 00:22:18 +00003604 if (clang_isStatement(C.kind))
3605 return cxloc::translateSourceLocation(getCursorContext(C),
3606 getCursorStmt(C)->getLocStart());
3607
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003608 if (C.kind == CXCursor_PreprocessingDirective) {
3609 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3610 return cxloc::translateSourceLocation(getCursorContext(C), L);
3611 }
Douglas Gregor48072312010-03-18 15:23:44 +00003612
3613 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003614 SourceLocation L
3615 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003616 return cxloc::translateSourceLocation(getCursorContext(C), L);
3617 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003618
3619 if (C.kind == CXCursor_MacroDefinition) {
3620 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3621 return cxloc::translateSourceLocation(getCursorContext(C), L);
3622 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003623
3624 if (C.kind == CXCursor_InclusionDirective) {
3625 SourceLocation L
3626 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3627 return cxloc::translateSourceLocation(getCursorContext(C), L);
3628 }
3629
Ted Kremenek9a700d22010-05-12 06:16:13 +00003630 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003631 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003632
Douglas Gregorf46034a2010-01-18 23:41:10 +00003633 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003634 SourceLocation Loc = D->getLocation();
3635 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3636 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003637 // FIXME: Multiple variables declared in a single declaration
3638 // currently lack the information needed to correctly determine their
3639 // ranges when accounting for the type-specifier. We use context
3640 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3641 // and if so, whether it is the first decl.
3642 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3643 if (!cxcursor::isFirstInDeclGroup(C))
3644 Loc = VD->getLocation();
3645 }
3646
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003647 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003648}
Douglas Gregora7bde202010-01-19 00:34:46 +00003649
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003650} // end extern "C"
3651
3652static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003653 if (clang_isReference(C.kind)) {
3654 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003655 case CXCursor_ObjCSuperClassRef:
3656 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003657
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003658 case CXCursor_ObjCProtocolRef:
3659 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003660
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003661 case CXCursor_ObjCClassRef:
3662 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003663
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003664 case CXCursor_TypeRef:
3665 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003666
3667 case CXCursor_TemplateRef:
3668 return getCursorTemplateRef(C).second;
3669
Douglas Gregor69319002010-08-31 23:48:11 +00003670 case CXCursor_NamespaceRef:
3671 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003672
3673 case CXCursor_MemberRef:
3674 return getCursorMemberRef(C).second;
3675
Ted Kremenek3064ef92010-08-27 21:34:58 +00003676 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003677 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003678
Douglas Gregor36897b02010-09-10 00:22:18 +00003679 case CXCursor_LabelRef:
3680 return getCursorLabelRef(C).second;
3681
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003682 case CXCursor_OverloadedDeclRef:
3683 return getCursorOverloadedDeclRef(C).second;
3684
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003685 default:
3686 // FIXME: Need a way to enumerate all non-reference cases.
3687 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003688 }
3689 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003690
3691 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003692 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003693
3694 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003695 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003696
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003697 if (C.kind == CXCursor_PreprocessingDirective)
3698 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003699
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003700 if (C.kind == CXCursor_MacroInstantiation)
3701 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003702
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003703 if (C.kind == CXCursor_MacroDefinition)
3704 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003705
3706 if (C.kind == CXCursor_InclusionDirective)
3707 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3708
Ted Kremenek007a7c92010-11-01 23:26:51 +00003709 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3710 Decl *D = cxcursor::getCursorDecl(C);
3711 SourceRange R = D->getSourceRange();
3712 // FIXME: Multiple variables declared in a single declaration
3713 // currently lack the information needed to correctly determine their
3714 // ranges when accounting for the type-specifier. We use context
3715 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3716 // and if so, whether it is the first decl.
3717 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3718 if (!cxcursor::isFirstInDeclGroup(C))
3719 R.setBegin(VD->getLocation());
3720 }
3721 return R;
3722 }
Douglas Gregor66537982010-11-17 17:14:07 +00003723 return SourceRange();
3724}
3725
3726/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3727/// the decl-specifier-seq for declarations.
3728static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3729 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3730 Decl *D = cxcursor::getCursorDecl(C);
3731 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003732
Douglas Gregor2494dd02011-03-01 01:34:45 +00003733 // Adjust the start of the location for declarations preceded by
3734 // declaration specifiers.
3735 SourceLocation StartLoc;
3736 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3737 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3738 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3739 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3740 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3741 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3742 }
3743
3744 if (StartLoc.isValid() && R.getBegin().isValid() &&
3745 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3746 R.setBegin(StartLoc);
3747
3748 // FIXME: Multiple variables declared in a single declaration
3749 // currently lack the information needed to correctly determine their
3750 // ranges when accounting for the type-specifier. We use context
3751 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3752 // and if so, whether it is the first decl.
3753 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3754 if (!cxcursor::isFirstInDeclGroup(C))
3755 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003756 }
3757
3758 return R;
3759 }
3760
3761 return getRawCursorExtent(C);
3762}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003763
3764extern "C" {
3765
3766CXSourceRange clang_getCursorExtent(CXCursor C) {
3767 SourceRange R = getRawCursorExtent(C);
3768 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003769 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003770
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003771 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003772}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003773
3774CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003775 if (clang_isInvalid(C.kind))
3776 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003777
Ted Kremeneka60ed472010-11-16 08:15:36 +00003778 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003779 if (clang_isDeclaration(C.kind)) {
3780 Decl *D = getCursorDecl(C);
3781 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003782 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003783 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003784 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003785 if (ObjCForwardProtocolDecl *Protocols
3786 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003787 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003788 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3789 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3790 return MakeCXCursor(Property, tu);
3791
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003792 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003793 }
3794
Douglas Gregor97b98722010-01-19 23:20:36 +00003795 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003796 Expr *E = getCursorExpr(C);
3797 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003798 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003799 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003800
3801 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003802 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003803
Douglas Gregor97b98722010-01-19 23:20:36 +00003804 return clang_getNullCursor();
3805 }
3806
Douglas Gregor36897b02010-09-10 00:22:18 +00003807 if (clang_isStatement(C.kind)) {
3808 Stmt *S = getCursorStmt(C);
3809 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek37c2e962011-03-15 23:47:49 +00003810 if (LabelDecl *label = Goto->getLabel())
3811 if (LabelStmt *labelS = label->getStmt())
3812 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003813
3814 return clang_getNullCursor();
3815 }
3816
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003817 if (C.kind == CXCursor_MacroInstantiation) {
3818 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003819 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003820 }
3821
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003822 if (!clang_isReference(C.kind))
3823 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003824
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003825 switch (C.kind) {
3826 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003827 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003828
3829 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003830 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003831
3832 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003833 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003834
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003835 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003836 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003837
3838 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003839 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003840
Douglas Gregor69319002010-08-31 23:48:11 +00003841 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003842 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003843
Douglas Gregora67e03f2010-09-09 21:42:20 +00003844 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003845 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003846
Ted Kremenek3064ef92010-08-27 21:34:58 +00003847 case CXCursor_CXXBaseSpecifier: {
3848 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3849 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003850 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003851 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003852
Douglas Gregor36897b02010-09-10 00:22:18 +00003853 case CXCursor_LabelRef:
3854 // FIXME: We end up faking the "parent" declaration here because we
3855 // don't want to make CXCursor larger.
3856 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003857 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3858 .getTranslationUnitDecl(),
3859 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003860
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003861 case CXCursor_OverloadedDeclRef:
3862 return C;
3863
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003864 default:
3865 // We would prefer to enumerate all non-reference cursor kinds here.
3866 llvm_unreachable("Unhandled reference cursor kind");
3867 break;
3868 }
3869 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003870
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003871 return clang_getNullCursor();
3872}
3873
Douglas Gregorb6998662010-01-19 19:34:47 +00003874CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003875 if (clang_isInvalid(C.kind))
3876 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003877
Ted Kremeneka60ed472010-11-16 08:15:36 +00003878 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003879
Douglas Gregorb6998662010-01-19 19:34:47 +00003880 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003881 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003882 C = clang_getCursorReferenced(C);
3883 WasReference = true;
3884 }
3885
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003886 if (C.kind == CXCursor_MacroInstantiation)
3887 return clang_getCursorReferenced(C);
3888
Douglas Gregorb6998662010-01-19 19:34:47 +00003889 if (!clang_isDeclaration(C.kind))
3890 return clang_getNullCursor();
3891
3892 Decl *D = getCursorDecl(C);
3893 if (!D)
3894 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003895
Douglas Gregorb6998662010-01-19 19:34:47 +00003896 switch (D->getKind()) {
3897 // Declaration kinds that don't really separate the notions of
3898 // declaration and definition.
3899 case Decl::Namespace:
3900 case Decl::Typedef:
Richard Smith162e1c12011-04-15 14:24:37 +00003901 case Decl::TypeAlias:
Douglas Gregorb6998662010-01-19 19:34:47 +00003902 case Decl::TemplateTypeParm:
3903 case Decl::EnumConstant:
3904 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003905 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003906 case Decl::ObjCIvar:
3907 case Decl::ObjCAtDefsField:
3908 case Decl::ImplicitParam:
3909 case Decl::ParmVar:
3910 case Decl::NonTypeTemplateParm:
3911 case Decl::TemplateTemplateParm:
3912 case Decl::ObjCCategoryImpl:
3913 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003914 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003915 case Decl::LinkageSpec:
3916 case Decl::ObjCPropertyImpl:
3917 case Decl::FileScopeAsm:
3918 case Decl::StaticAssert:
3919 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003920 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003921 return C;
3922
3923 // Declaration kinds that don't make any sense here, but are
3924 // nonetheless harmless.
3925 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003926 break;
3927
3928 // Declaration kinds for which the definition is not resolvable.
3929 case Decl::UnresolvedUsingTypename:
3930 case Decl::UnresolvedUsingValue:
3931 break;
3932
3933 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003934 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003935 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003936
3937 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003938 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003939
3940 case Decl::Enum:
3941 case Decl::Record:
3942 case Decl::CXXRecord:
3943 case Decl::ClassTemplateSpecialization:
3944 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003945 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003946 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003947 return clang_getNullCursor();
3948
3949 case Decl::Function:
3950 case Decl::CXXMethod:
3951 case Decl::CXXConstructor:
3952 case Decl::CXXDestructor:
3953 case Decl::CXXConversion: {
3954 const FunctionDecl *Def = 0;
3955 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003956 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003957 return clang_getNullCursor();
3958 }
3959
3960 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003961 // Ask the variable if it has a definition.
3962 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003963 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003964 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003965 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003966
Douglas Gregorb6998662010-01-19 19:34:47 +00003967 case Decl::FunctionTemplate: {
3968 const FunctionDecl *Def = 0;
3969 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003970 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003971 return clang_getNullCursor();
3972 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003973
Douglas Gregorb6998662010-01-19 19:34:47 +00003974 case Decl::ClassTemplate: {
3975 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003976 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003977 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003978 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003979 return clang_getNullCursor();
3980 }
3981
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003982 case Decl::Using:
3983 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003984 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003985
3986 case Decl::UsingShadow:
3987 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003988 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003989 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003990
3991 case Decl::ObjCMethod: {
3992 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3993 if (Method->isThisDeclarationADefinition())
3994 return C;
3995
3996 // Dig out the method definition in the associated
3997 // @implementation, if we have it.
3998 // FIXME: The ASTs should make finding the definition easier.
3999 if (ObjCInterfaceDecl *Class
4000 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4001 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4002 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4003 Method->isInstanceMethod()))
4004 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004005 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004006
4007 return clang_getNullCursor();
4008 }
4009
4010 case Decl::ObjCCategory:
4011 if (ObjCCategoryImplDecl *Impl
4012 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004013 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004014 return clang_getNullCursor();
4015
4016 case Decl::ObjCProtocol:
4017 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
4018 return C;
4019 return clang_getNullCursor();
4020
4021 case Decl::ObjCInterface:
4022 // There are two notions of a "definition" for an Objective-C
4023 // class: the interface and its implementation. When we resolved a
4024 // reference to an Objective-C class, produce the @interface as
4025 // the definition; when we were provided with the interface,
4026 // produce the @implementation as the definition.
4027 if (WasReference) {
4028 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4029 return C;
4030 } else if (ObjCImplementationDecl *Impl
4031 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004032 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004033 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004034
Douglas Gregorb6998662010-01-19 19:34:47 +00004035 case Decl::ObjCProperty:
4036 // FIXME: We don't really know where to find the
4037 // ObjCPropertyImplDecls that implement this property.
4038 return clang_getNullCursor();
4039
4040 case Decl::ObjCCompatibleAlias:
4041 if (ObjCInterfaceDecl *Class
4042 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4043 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004044 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004045
Douglas Gregorb6998662010-01-19 19:34:47 +00004046 return clang_getNullCursor();
4047
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004048 case Decl::ObjCForwardProtocol:
4049 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004050 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004051
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004052 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004053 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004054 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004055
4056 case Decl::Friend:
4057 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004058 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004059 return clang_getNullCursor();
4060
4061 case Decl::FriendTemplate:
4062 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004063 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004064 return clang_getNullCursor();
4065 }
4066
4067 return clang_getNullCursor();
4068}
4069
4070unsigned clang_isCursorDefinition(CXCursor C) {
4071 if (!clang_isDeclaration(C.kind))
4072 return 0;
4073
4074 return clang_getCursorDefinition(C) == C;
4075}
4076
Douglas Gregor1a9d0502010-11-19 23:44:15 +00004077CXCursor clang_getCanonicalCursor(CXCursor C) {
4078 if (!clang_isDeclaration(C.kind))
4079 return C;
4080
4081 if (Decl *D = getCursorDecl(C))
4082 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4083
4084 return C;
4085}
4086
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004087unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004088 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004089 return 0;
4090
4091 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4092 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4093 return E->getNumDecls();
4094
4095 if (OverloadedTemplateStorage *S
4096 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4097 return S->size();
4098
4099 Decl *D = Storage.get<Decl*>();
4100 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00004101 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004102 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4103 return Classes->size();
4104 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4105 return Protocols->protocol_size();
4106
4107 return 0;
4108}
4109
4110CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004111 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004112 return clang_getNullCursor();
4113
4114 if (index >= clang_getNumOverloadedDecls(cursor))
4115 return clang_getNullCursor();
4116
Ted Kremeneka60ed472010-11-16 08:15:36 +00004117 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004118 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4119 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004120 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004121
4122 if (OverloadedTemplateStorage *S
4123 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004124 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004125
4126 Decl *D = Storage.get<Decl*>();
4127 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4128 // FIXME: This is, unfortunately, linear time.
4129 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4130 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004131 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004132 }
4133
4134 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004135 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004136
4137 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004138 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004139
4140 return clang_getNullCursor();
4141}
4142
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004143void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004144 const char **startBuf,
4145 const char **endBuf,
4146 unsigned *startLine,
4147 unsigned *startColumn,
4148 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004149 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004150 assert(getCursorDecl(C) && "CXCursor has null decl");
4151 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004152 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4153 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004154
Steve Naroff4ade6d62009-09-23 17:52:52 +00004155 SourceManager &SM = FD->getASTContext().getSourceManager();
4156 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4157 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4158 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4159 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4160 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4161 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4162}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004163
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004164void clang_enableStackTraces(void) {
4165 llvm::sys::PrintStackTraceOnErrorSignal();
4166}
4167
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004168void clang_executeOnThread(void (*fn)(void*), void *user_data,
4169 unsigned stack_size) {
4170 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4171}
4172
Ted Kremenekfb480492010-01-13 21:46:36 +00004173} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004174
Ted Kremenekfb480492010-01-13 21:46:36 +00004175//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004176// Token-based Operations.
4177//===----------------------------------------------------------------------===//
4178
4179/* CXToken layout:
4180 * int_data[0]: a CXTokenKind
4181 * int_data[1]: starting token location
4182 * int_data[2]: token length
4183 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004184 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004185 * otherwise unused.
4186 */
4187extern "C" {
4188
4189CXTokenKind clang_getTokenKind(CXToken CXTok) {
4190 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4191}
4192
4193CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4194 switch (clang_getTokenKind(CXTok)) {
4195 case CXToken_Identifier:
4196 case CXToken_Keyword:
4197 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004198 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4199 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004200
4201 case CXToken_Literal: {
4202 // We have stashed the starting pointer in the ptr_data field. Use it.
4203 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004204 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004205 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004206
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004207 case CXToken_Punctuation:
4208 case CXToken_Comment:
4209 break;
4210 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004211
4212 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004213 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004214 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004215 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004216 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004217
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004218 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4219 std::pair<FileID, unsigned> LocInfo
4220 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004221 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004222 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004223 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4224 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004225 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004226
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004227 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004228}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004229
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004230CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004231 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004232 if (!CXXUnit)
4233 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004234
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004235 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4236 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4237}
4238
4239CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004240 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004241 if (!CXXUnit)
4242 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004243
4244 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004245 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4246}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004247
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004248void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4249 CXToken **Tokens, unsigned *NumTokens) {
4250 if (Tokens)
4251 *Tokens = 0;
4252 if (NumTokens)
4253 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004254
Ted Kremeneka60ed472010-11-16 08:15:36 +00004255 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004256 if (!CXXUnit || !Tokens || !NumTokens)
4257 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004258
Douglas Gregorbdf60622010-03-05 21:16:25 +00004259 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4260
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004261 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004262 if (R.isInvalid())
4263 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004264
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004265 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4266 std::pair<FileID, unsigned> BeginLocInfo
4267 = SourceMgr.getDecomposedLoc(R.getBegin());
4268 std::pair<FileID, unsigned> EndLocInfo
4269 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004270
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004271 // Cannot tokenize across files.
4272 if (BeginLocInfo.first != EndLocInfo.first)
4273 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004274
4275 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004276 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004277 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004278 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004279 if (Invalid)
4280 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004281
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004282 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4283 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004284 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004285 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004286
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004287 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004288 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004289 llvm::SmallVector<CXToken, 32> CXTokens;
4290 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004291 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004292 do {
4293 // Lex the next token
4294 Lex.LexFromRawLexer(Tok);
4295 if (Tok.is(tok::eof))
4296 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004297
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004298 // Initialize the CXToken.
4299 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004300
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004301 // - Common fields
4302 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4303 CXTok.int_data[2] = Tok.getLength();
4304 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004305
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004306 // - Kind-specific fields
4307 if (Tok.isLiteral()) {
4308 CXTok.int_data[0] = CXToken_Literal;
4309 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004310 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004311 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004312 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004313 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004314
David Chisnall096428b2010-10-13 21:44:48 +00004315 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004316 CXTok.int_data[0] = CXToken_Keyword;
4317 }
4318 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004319 CXTok.int_data[0] = Tok.is(tok::identifier)
4320 ? CXToken_Identifier
4321 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004322 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004323 CXTok.ptr_data = II;
4324 } else if (Tok.is(tok::comment)) {
4325 CXTok.int_data[0] = CXToken_Comment;
4326 CXTok.ptr_data = 0;
4327 } else {
4328 CXTok.int_data[0] = CXToken_Punctuation;
4329 CXTok.ptr_data = 0;
4330 }
4331 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004332 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004333 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004334
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004335 if (CXTokens.empty())
4336 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004337
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004338 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4339 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4340 *NumTokens = CXTokens.size();
4341}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004342
Ted Kremenek6db61092010-05-05 00:55:15 +00004343void clang_disposeTokens(CXTranslationUnit TU,
4344 CXToken *Tokens, unsigned NumTokens) {
4345 free(Tokens);
4346}
4347
4348} // end: extern "C"
4349
4350//===----------------------------------------------------------------------===//
4351// Token annotation APIs.
4352//===----------------------------------------------------------------------===//
4353
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004354typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004355static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4356 CXCursor parent,
4357 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004358namespace {
4359class AnnotateTokensWorker {
4360 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004361 CXToken *Tokens;
4362 CXCursor *Cursors;
4363 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004364 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004365 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004366 CursorVisitor AnnotateVis;
4367 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004368 bool HasContextSensitiveKeywords;
4369
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004370 bool MoreTokens() const { return TokIdx < NumTokens; }
4371 unsigned NextToken() const { return TokIdx; }
4372 void AdvanceToken() { ++TokIdx; }
4373 SourceLocation GetTokenLoc(unsigned tokI) {
4374 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4375 }
4376
Ted Kremenek6db61092010-05-05 00:55:15 +00004377public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004378 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004379 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004380 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004381 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004382 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004383 AnnotateVis(tu,
4384 AnnotateTokensVisitor, this,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00004385 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004386 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4387 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004388
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004389 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004390 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004391 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004392 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004393 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004394 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004395
4396 /// \brief Determine whether the annotator saw any cursors that have
4397 /// context-sensitive keywords.
4398 bool hasContextSensitiveKeywords() const {
4399 return HasContextSensitiveKeywords;
4400 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004401};
4402}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004403
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004404void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4405 // Walk the AST within the region of interest, annotating tokens
4406 // along the way.
4407 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004408
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004409 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4410 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004411 if (Pos != Annotated.end() &&
4412 (clang_isInvalid(Cursors[I].kind) ||
4413 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004414 Cursors[I] = Pos->second;
4415 }
4416
4417 // Finish up annotating any tokens left.
4418 if (!MoreTokens())
4419 return;
4420
4421 const CXCursor &C = clang_getNullCursor();
4422 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4423 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4424 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004425 }
4426}
4427
Ted Kremenek6db61092010-05-05 00:55:15 +00004428enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004429AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004430 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004431 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004432 if (cursorRange.isInvalid())
4433 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004434
4435 if (!HasContextSensitiveKeywords) {
4436 // Objective-C properties can have context-sensitive keywords.
4437 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4438 if (ObjCPropertyDecl *Property
4439 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4440 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4441 }
4442 // Objective-C methods can have context-sensitive keywords.
4443 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4444 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4445 if (ObjCMethodDecl *Method
4446 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4447 if (Method->getObjCDeclQualifier())
4448 HasContextSensitiveKeywords = true;
4449 else {
4450 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4451 PEnd = Method->param_end();
4452 P != PEnd; ++P) {
4453 if ((*P)->getObjCDeclQualifier()) {
4454 HasContextSensitiveKeywords = true;
4455 break;
4456 }
4457 }
4458 }
4459 }
4460 }
4461 // C++ methods can have context-sensitive keywords.
4462 else if (cursor.kind == CXCursor_CXXMethod) {
4463 if (CXXMethodDecl *Method
4464 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4465 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4466 HasContextSensitiveKeywords = true;
4467 }
4468 }
4469 // C++ classes can have context-sensitive keywords.
4470 else if (cursor.kind == CXCursor_StructDecl ||
4471 cursor.kind == CXCursor_ClassDecl ||
4472 cursor.kind == CXCursor_ClassTemplate ||
4473 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4474 if (Decl *D = getCursorDecl(cursor))
4475 if (D->hasAttr<FinalAttr>())
4476 HasContextSensitiveKeywords = true;
4477 }
4478 }
4479
Douglas Gregor4419b672010-10-21 06:10:04 +00004480 if (clang_isPreprocessing(cursor.kind)) {
4481 // For macro instantiations, just note where the beginning of the macro
4482 // instantiation occurs.
4483 if (cursor.kind == CXCursor_MacroInstantiation) {
4484 Annotated[Loc.int_data] = cursor;
4485 return CXChildVisit_Recurse;
4486 }
4487
Douglas Gregor4419b672010-10-21 06:10:04 +00004488 // Items in the preprocessing record are kept separate from items in
4489 // declarations, so we keep a separate token index.
4490 unsigned SavedTokIdx = TokIdx;
4491 TokIdx = PreprocessingTokIdx;
4492
4493 // Skip tokens up until we catch up to the beginning of the preprocessing
4494 // entry.
4495 while (MoreTokens()) {
4496 const unsigned I = NextToken();
4497 SourceLocation TokLoc = GetTokenLoc(I);
4498 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4499 case RangeBefore:
4500 AdvanceToken();
4501 continue;
4502 case RangeAfter:
4503 case RangeOverlap:
4504 break;
4505 }
4506 break;
4507 }
4508
4509 // Look at all of the tokens within this range.
4510 while (MoreTokens()) {
4511 const unsigned I = NextToken();
4512 SourceLocation TokLoc = GetTokenLoc(I);
4513 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4514 case RangeBefore:
4515 assert(0 && "Infeasible");
4516 case RangeAfter:
4517 break;
4518 case RangeOverlap:
4519 Cursors[I] = cursor;
4520 AdvanceToken();
4521 continue;
4522 }
4523 break;
4524 }
4525
4526 // Save the preprocessing token index; restore the non-preprocessing
4527 // token index.
4528 PreprocessingTokIdx = TokIdx;
4529 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004530 return CXChildVisit_Recurse;
4531 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004532
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004533 if (cursorRange.isInvalid())
4534 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004535
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004536 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4537
Ted Kremeneka333c662010-05-12 05:29:33 +00004538 // Adjust the annotated range based specific declarations.
4539 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4540 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004541 Decl *D = cxcursor::getCursorDecl(cursor);
4542 // Don't visit synthesized ObjC methods, since they have no syntatic
4543 // representation in the source.
4544 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4545 if (MD->isSynthesized())
4546 return CXChildVisit_Continue;
4547 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004548
4549 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004550 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004551 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4552 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4553 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4554 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4555 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004556 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004557
4558 if (StartLoc.isValid() && L.isValid() &&
4559 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4560 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004561 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004562
Ted Kremenek3f404602010-08-14 01:14:06 +00004563 // If the location of the cursor occurs within a macro instantiation, record
4564 // the spelling location of the cursor in our annotation map. We can then
4565 // paper over the token labelings during a post-processing step to try and
4566 // get cursor mappings for tokens that are the *arguments* of a macro
4567 // instantiation.
4568 if (L.isMacroID()) {
4569 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4570 // Only invalidate the old annotation if it isn't part of a preprocessing
4571 // directive. Here we assume that the default construction of CXCursor
4572 // results in CXCursor.kind being an initialized value (i.e., 0). If
4573 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004574
Ted Kremenek3f404602010-08-14 01:14:06 +00004575 CXCursor &oldC = Annotated[rawEncoding];
4576 if (!clang_isPreprocessing(oldC.kind))
4577 oldC = cursor;
4578 }
4579
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004580 const enum CXCursorKind K = clang_getCursorKind(parent);
4581 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004582 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4583 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004584
4585 while (MoreTokens()) {
4586 const unsigned I = NextToken();
4587 SourceLocation TokLoc = GetTokenLoc(I);
4588 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4589 case RangeBefore:
4590 Cursors[I] = updateC;
4591 AdvanceToken();
4592 continue;
4593 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004594 case RangeOverlap:
4595 break;
4596 }
4597 break;
4598 }
4599
4600 // Visit children to get their cursor information.
4601 const unsigned BeforeChildren = NextToken();
4602 VisitChildren(cursor);
4603 const unsigned AfterChildren = NextToken();
4604
4605 // Adjust 'Last' to the last token within the extent of the cursor.
4606 while (MoreTokens()) {
4607 const unsigned I = NextToken();
4608 SourceLocation TokLoc = GetTokenLoc(I);
4609 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4610 case RangeBefore:
4611 assert(0 && "Infeasible");
4612 case RangeAfter:
4613 break;
4614 case RangeOverlap:
4615 Cursors[I] = updateC;
4616 AdvanceToken();
4617 continue;
4618 }
4619 break;
4620 }
4621 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004622
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004623 // Scan the tokens that are at the beginning of the cursor, but are not
4624 // capture by the child cursors.
4625
4626 // For AST elements within macros, rely on a post-annotate pass to
4627 // to correctly annotate the tokens with cursors. Otherwise we can
4628 // get confusing results of having tokens that map to cursors that really
4629 // are expanded by an instantiation.
4630 if (L.isMacroID())
4631 cursor = clang_getNullCursor();
4632
4633 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4634 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4635 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004636
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004637 Cursors[I] = cursor;
4638 }
4639 // Scan the tokens that are at the end of the cursor, but are not captured
4640 // but the child cursors.
4641 for (unsigned I = AfterChildren; I != Last; ++I)
4642 Cursors[I] = cursor;
4643
4644 TokIdx = Last;
4645 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004646}
4647
Ted Kremenek6db61092010-05-05 00:55:15 +00004648static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4649 CXCursor parent,
4650 CXClientData client_data) {
4651 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4652}
4653
Ted Kremenek6628a612011-03-18 22:51:30 +00004654namespace {
4655 struct clang_annotateTokens_Data {
4656 CXTranslationUnit TU;
4657 ASTUnit *CXXUnit;
4658 CXToken *Tokens;
4659 unsigned NumTokens;
4660 CXCursor *Cursors;
4661 };
4662}
4663
Ted Kremenekab979612010-11-11 08:05:23 +00004664// This gets run a separate thread to avoid stack blowout.
Ted Kremenek6628a612011-03-18 22:51:30 +00004665static void clang_annotateTokensImpl(void *UserData) {
4666 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4667 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4668 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4669 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4670 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4671
4672 // Determine the region of interest, which contains all of the tokens.
4673 SourceRange RegionOfInterest;
4674 RegionOfInterest.setBegin(
4675 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4676 RegionOfInterest.setEnd(
4677 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4678 Tokens[NumTokens-1])));
4679
4680 // A mapping from the source locations found when re-lexing or traversing the
4681 // region of interest to the corresponding cursors.
4682 AnnotateTokensData Annotated;
4683
4684 // Relex the tokens within the source range to look for preprocessing
4685 // directives.
4686 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4687 std::pair<FileID, unsigned> BeginLocInfo
4688 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4689 std::pair<FileID, unsigned> EndLocInfo
4690 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4691
4692 llvm::StringRef Buffer;
4693 bool Invalid = false;
4694 if (BeginLocInfo.first == EndLocInfo.first &&
4695 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4696 !Invalid) {
4697 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4698 CXXUnit->getASTContext().getLangOptions(),
4699 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4700 Buffer.end());
4701 Lex.SetCommentRetentionState(true);
4702
4703 // Lex tokens in raw mode until we hit the end of the range, to avoid
4704 // entering #includes or expanding macros.
4705 while (true) {
4706 Token Tok;
4707 Lex.LexFromRawLexer(Tok);
4708
4709 reprocess:
4710 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4711 // We have found a preprocessing directive. Gobble it up so that we
4712 // don't see it while preprocessing these tokens later, but keep track
4713 // of all of the token locations inside this preprocessing directive so
4714 // that we can annotate them appropriately.
4715 //
4716 // FIXME: Some simple tests here could identify macro definitions and
4717 // #undefs, to provide specific cursor kinds for those.
4718 llvm::SmallVector<SourceLocation, 32> Locations;
4719 do {
4720 Locations.push_back(Tok.getLocation());
4721 Lex.LexFromRawLexer(Tok);
4722 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4723
4724 using namespace cxcursor;
4725 CXCursor Cursor
4726 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4727 Locations.back()),
4728 TU);
4729 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4730 Annotated[Locations[I].getRawEncoding()] = Cursor;
4731 }
4732
4733 if (Tok.isAtStartOfLine())
4734 goto reprocess;
4735
4736 continue;
4737 }
4738
4739 if (Tok.is(tok::eof))
4740 break;
4741 }
4742 }
4743
4744 // Annotate all of the source locations in the region of interest that map to
4745 // a specific cursor.
4746 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4747 TU, RegionOfInterest);
4748
4749 // FIXME: We use a ridiculous stack size here because the data-recursion
4750 // algorithm uses a large stack frame than the non-data recursive version,
4751 // and AnnotationTokensWorker currently transforms the data-recursion
4752 // algorithm back into a traditional recursion by explicitly calling
4753 // VisitChildren(). We will need to remove this explicit recursive call.
4754 W.AnnotateTokens();
4755
4756 // If we ran into any entities that involve context-sensitive keywords,
4757 // take another pass through the tokens to mark them as such.
4758 if (W.hasContextSensitiveKeywords()) {
4759 for (unsigned I = 0; I != NumTokens; ++I) {
4760 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4761 continue;
4762
4763 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4764 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4765 if (ObjCPropertyDecl *Property
4766 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4767 if (Property->getPropertyAttributesAsWritten() != 0 &&
4768 llvm::StringSwitch<bool>(II->getName())
4769 .Case("readonly", true)
4770 .Case("assign", true)
4771 .Case("readwrite", true)
4772 .Case("retain", true)
4773 .Case("copy", true)
4774 .Case("nonatomic", true)
4775 .Case("atomic", true)
4776 .Case("getter", true)
4777 .Case("setter", true)
4778 .Default(false))
4779 Tokens[I].int_data[0] = CXToken_Keyword;
4780 }
4781 continue;
4782 }
4783
4784 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4785 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4786 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4787 if (llvm::StringSwitch<bool>(II->getName())
4788 .Case("in", true)
4789 .Case("out", true)
4790 .Case("inout", true)
4791 .Case("oneway", true)
4792 .Case("bycopy", true)
4793 .Case("byref", true)
4794 .Default(false))
4795 Tokens[I].int_data[0] = CXToken_Keyword;
4796 continue;
4797 }
4798
4799 if (Cursors[I].kind == CXCursor_CXXMethod) {
4800 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4801 if (CXXMethodDecl *Method
4802 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4803 if ((Method->hasAttr<FinalAttr>() ||
4804 Method->hasAttr<OverrideAttr>()) &&
4805 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4806 llvm::StringSwitch<bool>(II->getName())
4807 .Case("final", true)
4808 .Case("override", true)
4809 .Default(false))
4810 Tokens[I].int_data[0] = CXToken_Keyword;
4811 }
4812 continue;
4813 }
4814
4815 if (Cursors[I].kind == CXCursor_ClassDecl ||
4816 Cursors[I].kind == CXCursor_StructDecl ||
4817 Cursors[I].kind == CXCursor_ClassTemplate) {
4818 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4819 if (II->getName() == "final") {
4820 // We have to be careful with 'final', since it could be the name
4821 // of a member class rather than the context-sensitive keyword.
4822 // So, check whether the cursor associated with this
4823 Decl *D = getCursorDecl(Cursors[I]);
4824 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4825 if ((Record->hasAttr<FinalAttr>()) &&
4826 Record->getIdentifier() != II)
4827 Tokens[I].int_data[0] = CXToken_Keyword;
4828 } else if (ClassTemplateDecl *ClassTemplate
4829 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4830 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4831 if ((Record->hasAttr<FinalAttr>()) &&
4832 Record->getIdentifier() != II)
4833 Tokens[I].int_data[0] = CXToken_Keyword;
4834 }
4835 }
4836 continue;
4837 }
4838 }
4839 }
Ted Kremenekab979612010-11-11 08:05:23 +00004840}
4841
Ted Kremenek6db61092010-05-05 00:55:15 +00004842extern "C" {
4843
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004844void clang_annotateTokens(CXTranslationUnit TU,
4845 CXToken *Tokens, unsigned NumTokens,
4846 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004847
4848 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004849 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004850
Douglas Gregor4419b672010-10-21 06:10:04 +00004851 // Any token we don't specifically annotate will have a NULL cursor.
4852 CXCursor C = clang_getNullCursor();
4853 for (unsigned I = 0; I != NumTokens; ++I)
4854 Cursors[I] = C;
4855
Ted Kremeneka60ed472010-11-16 08:15:36 +00004856 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004857 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004858 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004859
Douglas Gregorbdf60622010-03-05 21:16:25 +00004860 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek6628a612011-03-18 22:51:30 +00004861
4862 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekab979612010-11-11 08:05:23 +00004863 llvm::CrashRecoveryContext CRC;
Ted Kremenek6628a612011-03-18 22:51:30 +00004864 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004865 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004866 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4867 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004868}
Ted Kremenek6628a612011-03-18 22:51:30 +00004869
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004870} // end: extern "C"
4871
4872//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004873// Operations for querying linkage of a cursor.
4874//===----------------------------------------------------------------------===//
4875
4876extern "C" {
4877CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004878 if (!clang_isDeclaration(cursor.kind))
4879 return CXLinkage_Invalid;
4880
Ted Kremenek16b42592010-03-03 06:36:57 +00004881 Decl *D = cxcursor::getCursorDecl(cursor);
4882 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4883 switch (ND->getLinkage()) {
4884 case NoLinkage: return CXLinkage_NoLinkage;
4885 case InternalLinkage: return CXLinkage_Internal;
4886 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4887 case ExternalLinkage: return CXLinkage_External;
4888 };
4889
4890 return CXLinkage_Invalid;
4891}
4892} // end: extern "C"
4893
4894//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004895// Operations for querying language of a cursor.
4896//===----------------------------------------------------------------------===//
4897
4898static CXLanguageKind getDeclLanguage(const Decl *D) {
4899 switch (D->getKind()) {
4900 default:
4901 break;
4902 case Decl::ImplicitParam:
4903 case Decl::ObjCAtDefsField:
4904 case Decl::ObjCCategory:
4905 case Decl::ObjCCategoryImpl:
4906 case Decl::ObjCClass:
4907 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004908 case Decl::ObjCForwardProtocol:
4909 case Decl::ObjCImplementation:
4910 case Decl::ObjCInterface:
4911 case Decl::ObjCIvar:
4912 case Decl::ObjCMethod:
4913 case Decl::ObjCProperty:
4914 case Decl::ObjCPropertyImpl:
4915 case Decl::ObjCProtocol:
4916 return CXLanguage_ObjC;
4917 case Decl::CXXConstructor:
4918 case Decl::CXXConversion:
4919 case Decl::CXXDestructor:
4920 case Decl::CXXMethod:
4921 case Decl::CXXRecord:
4922 case Decl::ClassTemplate:
4923 case Decl::ClassTemplatePartialSpecialization:
4924 case Decl::ClassTemplateSpecialization:
4925 case Decl::Friend:
4926 case Decl::FriendTemplate:
4927 case Decl::FunctionTemplate:
4928 case Decl::LinkageSpec:
4929 case Decl::Namespace:
4930 case Decl::NamespaceAlias:
4931 case Decl::NonTypeTemplateParm:
4932 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004933 case Decl::TemplateTemplateParm:
4934 case Decl::TemplateTypeParm:
4935 case Decl::UnresolvedUsingTypename:
4936 case Decl::UnresolvedUsingValue:
4937 case Decl::Using:
4938 case Decl::UsingDirective:
4939 case Decl::UsingShadow:
4940 return CXLanguage_CPlusPlus;
4941 }
4942
4943 return CXLanguage_C;
4944}
4945
4946extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004947
4948enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4949 if (clang_isDeclaration(cursor.kind))
4950 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004951 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregor58ddb602010-08-23 23:00:57 +00004952 return CXAvailability_Available;
4953
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004954 switch (D->getAvailability()) {
4955 case AR_Available:
4956 case AR_NotYetIntroduced:
4957 return CXAvailability_Available;
4958
4959 case AR_Deprecated:
Douglas Gregor58ddb602010-08-23 23:00:57 +00004960 return CXAvailability_Deprecated;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004961
4962 case AR_Unavailable:
4963 return CXAvailability_NotAvailable;
4964 }
Douglas Gregor58ddb602010-08-23 23:00:57 +00004965 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004966
Douglas Gregor58ddb602010-08-23 23:00:57 +00004967 return CXAvailability_Available;
4968}
4969
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004970CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4971 if (clang_isDeclaration(cursor.kind))
4972 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4973
4974 return CXLanguage_Invalid;
4975}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004976
4977 /// \brief If the given cursor is the "templated" declaration
4978 /// descibing a class or function template, return the class or
4979 /// function template.
4980static Decl *maybeGetTemplateCursor(Decl *D) {
4981 if (!D)
4982 return 0;
4983
4984 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4985 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4986 return FunTmpl;
4987
4988 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4989 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4990 return ClassTmpl;
4991
4992 return D;
4993}
4994
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004995CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4996 if (clang_isDeclaration(cursor.kind)) {
4997 if (Decl *D = getCursorDecl(cursor)) {
4998 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004999 if (!DC)
5000 return clang_getNullCursor();
5001
5002 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5003 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005004 }
5005 }
5006
5007 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
5008 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00005009 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005010 }
5011
5012 return clang_getNullCursor();
5013}
5014
5015CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5016 if (clang_isDeclaration(cursor.kind)) {
5017 if (Decl *D = getCursorDecl(cursor)) {
5018 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00005019 if (!DC)
5020 return clang_getNullCursor();
5021
5022 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5023 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005024 }
5025 }
5026
5027 // FIXME: Note that we can't easily compute the lexical context of a
5028 // statement or expression, so we return nothing.
5029 return clang_getNullCursor();
5030}
5031
Douglas Gregor9f592342010-10-01 20:25:15 +00005032static void CollectOverriddenMethods(DeclContext *Ctx,
5033 ObjCMethodDecl *Method,
5034 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5035 if (!Ctx)
5036 return;
5037
5038 // If we have a class or category implementation, jump straight to the
5039 // interface.
5040 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5041 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5042
5043 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5044 if (!Container)
5045 return;
5046
5047 // Check whether we have a matching method at this level.
5048 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5049 Method->isInstanceMethod()))
5050 if (Method != Overridden) {
5051 // We found an override at this level; there is no need to look
5052 // into other protocols or categories.
5053 Methods.push_back(Overridden);
5054 return;
5055 }
5056
5057 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5058 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5059 PEnd = Protocol->protocol_end();
5060 P != PEnd; ++P)
5061 CollectOverriddenMethods(*P, Method, Methods);
5062 }
5063
5064 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5065 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5066 PEnd = Category->protocol_end();
5067 P != PEnd; ++P)
5068 CollectOverriddenMethods(*P, Method, Methods);
5069 }
5070
5071 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5072 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5073 PEnd = Interface->protocol_end();
5074 P != PEnd; ++P)
5075 CollectOverriddenMethods(*P, Method, Methods);
5076
5077 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5078 Category; Category = Category->getNextClassCategory())
5079 CollectOverriddenMethods(Category, Method, Methods);
5080
5081 // We only look into the superclass if we haven't found anything yet.
5082 if (Methods.empty())
5083 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5084 return CollectOverriddenMethods(Super, Method, Methods);
5085 }
5086}
5087
5088void clang_getOverriddenCursors(CXCursor cursor,
5089 CXCursor **overridden,
5090 unsigned *num_overridden) {
5091 if (overridden)
5092 *overridden = 0;
5093 if (num_overridden)
5094 *num_overridden = 0;
5095 if (!overridden || !num_overridden)
5096 return;
5097
5098 if (!clang_isDeclaration(cursor.kind))
5099 return;
5100
5101 Decl *D = getCursorDecl(cursor);
5102 if (!D)
5103 return;
5104
5105 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00005106 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00005107 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5108 *num_overridden = CXXMethod->size_overridden_methods();
5109 if (!*num_overridden)
5110 return;
5111
5112 *overridden = new CXCursor [*num_overridden];
5113 unsigned I = 0;
5114 for (CXXMethodDecl::method_iterator
5115 M = CXXMethod->begin_overridden_methods(),
5116 MEnd = CXXMethod->end_overridden_methods();
5117 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005118 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005119 return;
5120 }
5121
5122 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5123 if (!Method)
5124 return;
5125
5126 // Handle Objective-C methods.
5127 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5128 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5129
5130 if (Methods.empty())
5131 return;
5132
5133 *num_overridden = Methods.size();
5134 *overridden = new CXCursor [Methods.size()];
5135 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005136 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005137}
5138
5139void clang_disposeOverriddenCursors(CXCursor *overridden) {
5140 delete [] overridden;
5141}
5142
Douglas Gregorecdcb882010-10-20 22:00:55 +00005143CXFile clang_getIncludedFile(CXCursor cursor) {
5144 if (cursor.kind != CXCursor_InclusionDirective)
5145 return 0;
5146
5147 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5148 return (void *)ID->getFile();
5149}
5150
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005151} // end: extern "C"
5152
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005153
5154//===----------------------------------------------------------------------===//
5155// C++ AST instrospection.
5156//===----------------------------------------------------------------------===//
5157
5158extern "C" {
5159unsigned clang_CXXMethod_isStatic(CXCursor C) {
5160 if (!clang_isDeclaration(C.kind))
5161 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005162
5163 CXXMethodDecl *Method = 0;
5164 Decl *D = cxcursor::getCursorDecl(C);
5165 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5166 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5167 else
5168 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5169 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005170}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005171
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005172} // end: extern "C"
5173
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005174//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005175// Attribute introspection.
5176//===----------------------------------------------------------------------===//
5177
5178extern "C" {
5179CXType clang_getIBOutletCollectionType(CXCursor C) {
5180 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005181 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005182
5183 IBOutletCollectionAttr *A =
5184 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5185
Douglas Gregor841b2382011-03-06 18:55:32 +00005186 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005187}
5188} // end: extern "C"
5189
5190//===----------------------------------------------------------------------===//
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005191// Inspecting memory usage.
5192//===----------------------------------------------------------------------===//
5193
Ted Kremenekf7870022011-04-20 16:41:07 +00005194typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005195
Ted Kremenekf7870022011-04-20 16:41:07 +00005196static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
5197 enum CXTUResourceUsageKind k,
Ted Kremenekba29bd22011-04-28 04:53:38 +00005198 unsigned long amount) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005199 CXTUResourceUsageEntry entry = { k, amount };
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005200 entries.push_back(entry);
5201}
5202
5203extern "C" {
5204
Ted Kremenekf7870022011-04-20 16:41:07 +00005205const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005206 const char *str = "";
5207 switch (kind) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005208 case CXTUResourceUsage_AST:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005209 str = "ASTContext: expressions, declarations, and types";
5210 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005211 case CXTUResourceUsage_Identifiers:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005212 str = "ASTContext: identifiers";
5213 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005214 case CXTUResourceUsage_Selectors:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005215 str = "ASTContext: selectors";
Ted Kremeneke294ab72011-04-19 04:36:17 +00005216 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005217 case CXTUResourceUsage_GlobalCompletionResults:
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005218 str = "Code completion: cached global results";
Ted Kremeneke294ab72011-04-19 04:36:17 +00005219 break;
Ted Kremenek457aaf02011-04-28 04:10:31 +00005220 case CXTUResourceUsage_SourceManagerContentCache:
5221 str = "SourceManager: content cache allocator";
5222 break;
Ted Kremenekba29bd22011-04-28 04:53:38 +00005223 case CXTUResourceUsage_AST_SideTables:
5224 str = "ASTContext: side tables";
5225 break;
Ted Kremenekf61b8312011-04-28 20:36:42 +00005226 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
5227 str = "SourceManager: malloc'ed memory buffers";
5228 break;
5229 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
5230 str = "SourceManager: mmap'ed memory buffers";
5231 break;
Ted Kremeneke9b5f3d2011-04-28 23:46:20 +00005232 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
5233 str = "ExternalASTSource: malloc'ed memory buffers";
5234 break;
5235 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
5236 str = "ExternalASTSource: mmap'ed memory buffers";
5237 break;
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005238 }
5239 return str;
5240}
5241
Ted Kremenekf7870022011-04-20 16:41:07 +00005242CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005243 if (!TU) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005244 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005245 return usage;
5246 }
5247
5248 ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
5249 llvm::OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
5250 ASTContext &astContext = astUnit->getASTContext();
5251
5252 // How much memory is used by AST nodes and types?
Ted Kremenekf7870022011-04-20 16:41:07 +00005253 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
Ted Kremenekba29bd22011-04-28 04:53:38 +00005254 (unsigned long) astContext.getASTAllocatedMemory());
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005255
5256 // How much memory is used by identifiers?
Ted Kremenekf7870022011-04-20 16:41:07 +00005257 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005258 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
5259
5260 // How much memory is used for selectors?
Ted Kremenekf7870022011-04-20 16:41:07 +00005261 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005262 (unsigned long) astContext.Selectors.getTotalMemory());
5263
Ted Kremenekba29bd22011-04-28 04:53:38 +00005264 // How much memory is used by ASTContext's side tables?
5265 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
5266 (unsigned long) astContext.getSideTableAllocatedMemory());
5267
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005268 // How much memory is used for caching global code completion results?
5269 unsigned long completionBytes = 0;
5270 if (GlobalCodeCompletionAllocator *completionAllocator =
5271 astUnit->getCachedCompletionAllocator().getPtr()) {
5272 completionBytes = completionAllocator-> getTotalMemory();
5273 }
Ted Kremenek457aaf02011-04-28 04:10:31 +00005274 createCXTUResourceUsageEntry(*entries,
5275 CXTUResourceUsage_GlobalCompletionResults,
5276 completionBytes);
5277
5278 // How much memory is being used by SourceManager's content cache?
5279 createCXTUResourceUsageEntry(*entries,
5280 CXTUResourceUsage_SourceManagerContentCache,
5281 (unsigned long) astContext.getSourceManager().getContentCacheSize());
Ted Kremenekf61b8312011-04-28 20:36:42 +00005282
5283 // How much memory is being used by the MemoryBuffer's in SourceManager?
5284 const SourceManager::MemoryBufferSizes &srcBufs =
5285 astUnit->getSourceManager().getMemoryBufferSizes();
5286
5287 createCXTUResourceUsageEntry(*entries,
5288 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
5289 (unsigned long) srcBufs.malloc_bytes);
Ted Kremeneke9b5f3d2011-04-28 23:46:20 +00005290 createCXTUResourceUsageEntry(*entries,
Ted Kremenekf61b8312011-04-28 20:36:42 +00005291 CXTUResourceUsage_SourceManager_Membuffer_MMap,
5292 (unsigned long) srcBufs.mmap_bytes);
Ted Kremeneke9b5f3d2011-04-28 23:46:20 +00005293
5294 // How much memory is being used by the ExternalASTSource?
5295 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
5296 const ExternalASTSource::MemoryBufferSizes &sizes =
5297 esrc->getMemoryBufferSizes();
5298
5299 createCXTUResourceUsageEntry(*entries,
5300 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
5301 (unsigned long) sizes.malloc_bytes);
5302 createCXTUResourceUsageEntry(*entries,
5303 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
5304 (unsigned long) sizes.mmap_bytes);
5305 }
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005306
Ted Kremenekf7870022011-04-20 16:41:07 +00005307 CXTUResourceUsage usage = { (void*) entries.get(),
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005308 (unsigned) entries->size(),
5309 entries->size() ? &(*entries)[0] : 0 };
5310 entries.take();
5311 return usage;
5312}
5313
Ted Kremenekf7870022011-04-20 16:41:07 +00005314void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005315 if (usage.data)
5316 delete (MemUsageEntries*) usage.data;
5317}
5318
5319} // end extern "C"
5320
5321//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005322// Misc. utility functions.
5323//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005324
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005325/// Default to using an 8 MB stack size on "safety" threads.
5326static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005327
5328namespace clang {
5329
5330bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005331 void (*Fn)(void*), void *UserData,
5332 unsigned Size) {
5333 if (!Size)
5334 Size = GetSafetyThreadStackSize();
5335 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005336 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5337 return CRC.RunSafely(Fn, UserData);
5338}
5339
5340unsigned GetSafetyThreadStackSize() {
5341 return SafetyStackThreadSize;
5342}
5343
5344void SetSafetyThreadStackSize(unsigned Value) {
5345 SafetyStackThreadSize = Value;
5346}
5347
5348}
5349
Ted Kremenek04bb7162010-01-22 22:44:15 +00005350extern "C" {
5351
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005352CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005353 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005354}
5355
5356} // end: extern "C"
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005357