blob: 3c585ed2b0277565443e3e698b1747e59cefe6cb [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 Kremenek95f33552010-08-26 01:42:22 +000017#include "CXType.h"
Ted Kremeneka297de22010-01-25 22:34:44 +000018#include "CXSourceLocation.h"
Douglas Gregor5352ac02010-01-28 00:27:43 +000019#include "CIndexDiagnostic.h"
Ted Kremenekab188932010-01-05 19:32:54 +000020
Ted Kremenek04bb7162010-01-22 22:44:15 +000021#include "clang/Basic/Version.h"
Douglas Gregor936ea3b2010-01-28 00:56:43 +000022
Steve Naroff50398192009-08-28 15:28:48 +000023#include "clang/AST/DeclVisitor.h"
Steve Narofffb570422009-09-22 19:25:29 +000024#include "clang/AST/StmtVisitor.h"
Douglas Gregor7d0d40e2010-01-21 16:28:34 +000025#include "clang/AST/TypeLocVisitor.h"
Benjamin Kramerb846deb2010-04-12 19:45:50 +000026#include "clang/Basic/Diagnostic.h"
27#include "clang/Frontend/ASTUnit.h"
28#include "clang/Frontend/CompilerInstance.h"
Douglas Gregor936ea3b2010-01-28 00:56:43 +000029#include "clang/Frontend/FrontendDiagnostic.h"
Ted Kremenekd8210652010-01-06 23:43:31 +000030#include "clang/Lex/Lexer.h"
Benjamin Kramerb846deb2010-04-12 19:45:50 +000031#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregor33e9abd2010-01-22 19:49:59 +000032#include "clang/Lex/Preprocessor.h"
Douglas Gregora67e03f2010-09-09 21:42:20 +000033#include "llvm/ADT/STLExtras.h"
Ted Kremenekd8c370c2010-11-02 23:10:24 +000034#include "llvm/ADT/Optional.h"
35#include "clang/Analysis/Support/SaveAndRestore.h"
Daniel Dunbarc7df4f32010-08-18 18:43:14 +000036#include "llvm/Support/CrashRecoveryContext.h"
Daniel Dunbar48615ff2010-10-08 19:30:33 +000037#include "llvm/Support/PrettyStackTrace.h"
Douglas Gregor02465752009-10-16 21:24:31 +000038#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor358559d2010-10-02 22:49:11 +000039#include "llvm/Support/raw_ostream.h"
Douglas Gregor7a07fcb2010-08-09 21:00:09 +000040#include "llvm/Support/Timer.h"
Douglas Gregor8c8d5412010-09-24 21:18:36 +000041#include "llvm/System/Mutex.h"
Benjamin Kramer0829a832009-10-18 11:19:36 +000042#include "llvm/System/Program.h"
Douglas Gregor0a812cf2010-02-18 23:07:20 +000043#include "llvm/System/Signals.h"
Douglas Gregor8c8d5412010-09-24 21:18:36 +000044#include "llvm/System/Threading.h"
Ted Kremenekfc062212009-10-19 21:44:57 +000045
Benjamin Kramerc2a98162010-03-13 21:22:49 +000046// Needed to define L_TMPNAM on some systems.
47#include <cstdio>
48
Steve Naroff50398192009-08-28 15:28:48 +000049using namespace clang;
Ted Kremenek16c440a2010-01-15 20:35:54 +000050using namespace clang::cxcursor;
Ted Kremenekee4db4f2010-02-17 00:41:08 +000051using namespace clang::cxstring;
Steve Naroff50398192009-08-28 15:28:48 +000052
Douglas Gregor33e9abd2010-01-22 19:49:59 +000053/// \brief The result of comparing two source ranges.
54enum RangeComparisonResult {
55 /// \brief Either the ranges overlap or one of the ranges is invalid.
56 RangeOverlap,
Ted Kremenekf0e23e82010-02-17 00:41:40 +000057
Douglas Gregor33e9abd2010-01-22 19:49:59 +000058 /// \brief The first range ends before the second range starts.
59 RangeBefore,
Ted Kremenekf0e23e82010-02-17 00:41:40 +000060
Douglas Gregor33e9abd2010-01-22 19:49:59 +000061 /// \brief The first range starts after the second range ends.
62 RangeAfter
63};
64
Ted Kremenekf0e23e82010-02-17 00:41:40 +000065/// \brief Compare two source ranges to determine their relative position in
Douglas Gregor33e9abd2010-01-22 19:49:59 +000066/// the translation unit.
Ted Kremenekf0e23e82010-02-17 00:41:40 +000067static RangeComparisonResult RangeCompare(SourceManager &SM,
68 SourceRange R1,
Douglas Gregor33e9abd2010-01-22 19:49:59 +000069 SourceRange R2) {
70 assert(R1.isValid() && "First range is invalid?");
71 assert(R2.isValid() && "Second range is invalid?");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000072 if (R1.getEnd() != R2.getBegin() &&
Daniel Dunbard52864b2010-02-14 10:02:57 +000073 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
Douglas Gregor33e9abd2010-01-22 19:49:59 +000074 return RangeBefore;
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000075 if (R2.getEnd() != R1.getBegin() &&
Daniel Dunbard52864b2010-02-14 10:02:57 +000076 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
Douglas Gregor33e9abd2010-01-22 19:49:59 +000077 return RangeAfter;
78 return RangeOverlap;
79}
80
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000081/// \brief Determine if a source location falls within, before, or after a
82/// a given source range.
83static RangeComparisonResult LocationCompare(SourceManager &SM,
84 SourceLocation L, SourceRange R) {
85 assert(R.isValid() && "First range is invalid?");
86 assert(L.isValid() && "Second range is invalid?");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000087 if (L == R.getBegin() || L == R.getEnd())
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000088 return RangeOverlap;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000089 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
90 return RangeBefore;
91 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
92 return RangeAfter;
93 return RangeOverlap;
94}
95
Daniel Dunbar76dd3c22010-02-14 01:47:29 +000096/// \brief Translate a Clang source range into a CIndex source range.
97///
98/// Clang internally represents ranges where the end location points to the
99/// start of the token at the end. However, for external clients it is more
100/// useful to have a CXSourceRange be a proper half-open interval. This routine
101/// does the appropriate translation.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000102CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000103 const LangOptions &LangOpts,
Chris Lattner0a76aae2010-06-18 22:45:06 +0000104 const CharSourceRange &R) {
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000105 // We want the last character in this location, so we will adjust the
Douglas Gregor6a5a23f2010-03-19 21:51:54 +0000106 // location accordingly.
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000107 SourceLocation EndLoc = R.getEnd();
Douglas Gregora9b06d42010-11-09 06:24:54 +0000108 if (EndLoc.isValid() && EndLoc.isMacroID())
109 EndLoc = SM.getSpellingLoc(EndLoc);
Chris Lattner0a76aae2010-06-18 22:45:06 +0000110 if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +0000111 unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000112 EndLoc = EndLoc.getFileLocWithOffset(Length);
113 }
114
115 CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
116 R.getBegin().getRawEncoding(),
117 EndLoc.getRawEncoding() };
118 return Result;
119}
Douglas Gregor1db19de2010-01-19 21:36:55 +0000120
Ted Kremenek8a8da7d2010-01-06 03:42:32 +0000121//===----------------------------------------------------------------------===//
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000122// Cursor visitor.
Ted Kremenek8a8da7d2010-01-06 03:42:32 +0000123//===----------------------------------------------------------------------===//
124
Steve Naroff89922f82009-08-31 00:59:03 +0000125namespace {
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000126
127class VisitorJob {
128public:
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000129 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
130 TypeLocVisitKind };
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000131protected:
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000132 void *dataA;
133 void *dataB;
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000134 CXCursor parent;
135 Kind K;
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000136 VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0)
137 : dataA(d1), dataB(d2), parent(C), K(k) {}
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000138public:
139 Kind getKind() const { return K; }
140 const CXCursor &getParent() const { return parent; }
141 static bool classof(VisitorJob *VJ) { return true; }
142};
143
144typedef llvm::SmallVector<VisitorJob, 10> VisitorWorkList;
145
146#define DEF_JOB(NAME, DATA, KIND)\
147class NAME : public VisitorJob {\
148public:\
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000149 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000150 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000151 DATA *get() const { return static_cast<DATA*>(dataA); }\
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000152};
153
Ted Kremenekf1107452010-11-12 18:26:56 +0000154DEF_JOB(DeclVisit, Decl, DeclVisitKind)
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000155DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
156DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000157#undef DEF_JOB
158
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000159class TypeLocVisit : public VisitorJob {
160public:
161 TypeLocVisit(TypeLoc tl, CXCursor parent) :
162 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
163 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
164
165 static bool classof(const VisitorJob *VJ) {
166 return VJ->getKind() == TypeLocVisitKind;
167 }
168
169 TypeLoc get() {
170 QualType T = QualType::getFromOpaquePtr(dataA);
171 return TypeLoc(T, dataB);
172 }
173};
174
Ted Kremenekc70ebba2010-11-12 18:26:58 +0000175static inline void WLAddStmt(VisitorWorkList &WL, CXCursor Parent, Stmt *S) {
176 if (S)
177 WL.push_back(StmtVisit(S, Parent));
178}
179static inline void WLAddDecl(VisitorWorkList &WL, CXCursor Parent, Decl *D) {
180 if (D)
181 WL.push_back(DeclVisit(D, Parent));
182}
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000183static inline void WLAddTypeLoc(VisitorWorkList &WL, CXCursor Parent,
184 TypeSourceInfo *TI) {
185 if (TI)
186 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
187}
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000188
Douglas Gregorb1373d02010-01-20 20:59:29 +0000189// Cursor visitor.
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000190class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
Douglas Gregora59e3902010-01-21 23:27:09 +0000191 public TypeLocVisitor<CursorVisitor, bool>,
192 public StmtVisitor<CursorVisitor, bool>
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000193{
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000194 /// \brief The translation unit we are traversing.
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000195 ASTUnit *TU;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000196
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000197 /// \brief The parent cursor whose children we are traversing.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000198 CXCursor Parent;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000199
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000200 /// \brief The declaration that serves at the parent of any statement or
201 /// expression nodes.
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000202 Decl *StmtParent;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000203
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000204 /// \brief The visitor function.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000205 CXCursorVisitor Visitor;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000206
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000207 /// \brief The opaque client data, to be passed along to the visitor.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000208 CXClientData ClientData;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000209
Douglas Gregor7d1d49d2009-10-16 20:01:17 +0000210 // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
211 // to the visitor. Declarations with a PCH level greater than this value will
212 // be suppressed.
213 unsigned MaxPCHLevel;
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000214
215 /// \brief When valid, a source range to which the cursor should restrict
216 /// its search.
217 SourceRange RegionOfInterest;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000218
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000219 // FIXME: Eventually remove. This part of a hack to support proper
220 // iteration over all Decls contained lexically within an ObjC container.
221 DeclContext::decl_iterator *DI_current;
222 DeclContext::decl_iterator DE_current;
223
Douglas Gregorb1373d02010-01-20 20:59:29 +0000224 using DeclVisitor<CursorVisitor, bool>::Visit;
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000225 using TypeLocVisitor<CursorVisitor, bool>::Visit;
Douglas Gregora59e3902010-01-21 23:27:09 +0000226 using StmtVisitor<CursorVisitor, bool>::Visit;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000227
228 /// \brief Determine whether this particular source range comes before, comes
229 /// after, or overlaps the region of interest.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000230 ///
Daniel Dunbard52864b2010-02-14 10:02:57 +0000231 /// \param R a half-open source range retrieved from the abstract syntax tree.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000232 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
233
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000234 class SetParentRAII {
235 CXCursor &Parent;
236 Decl *&StmtParent;
237 CXCursor OldParent;
238
239 public:
240 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
241 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
242 {
243 Parent = NewParent;
244 if (clang_isDeclaration(Parent.kind))
245 StmtParent = getCursorDecl(Parent);
246 }
247
248 ~SetParentRAII() {
249 Parent = OldParent;
250 if (clang_isDeclaration(Parent.kind))
251 StmtParent = getCursorDecl(Parent);
252 }
253 };
254
Steve Naroff89922f82009-08-31 00:59:03 +0000255public:
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000256 CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData,
257 unsigned MaxPCHLevel,
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000258 SourceRange RegionOfInterest = SourceRange())
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000259 : TU(TU), Visitor(Visitor), ClientData(ClientData),
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000260 MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest),
261 DI_current(0)
Douglas Gregorb1373d02010-01-20 20:59:29 +0000262 {
263 Parent.kind = CXCursor_NoDeclFound;
264 Parent.data[0] = 0;
265 Parent.data[1] = 0;
266 Parent.data[2] = 0;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000267 StmtParent = 0;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000268 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000269
Ted Kremenekab979612010-11-11 08:05:23 +0000270 ASTUnit *getASTUnit() const { return TU; }
271
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000272 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000273
274 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
275 getPreprocessedEntities();
276
Douglas Gregorb1373d02010-01-20 20:59:29 +0000277 bool VisitChildren(CXCursor Parent);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000278
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000279 // Declaration visitors
Ted Kremenek09dfa372010-02-18 05:46:33 +0000280 bool VisitAttributes(Decl *D);
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000281 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenek3064ef92010-08-27 21:34:58 +0000282 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000283 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000284 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000285 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
286 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000287 bool VisitTagDecl(TagDecl *D);
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000288 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregor74dbe642010-08-31 19:31:58 +0000289 bool VisitClassTemplatePartialSpecializationDecl(
290 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000291 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000292 bool VisitEnumConstantDecl(EnumConstantDecl *D);
293 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
294 bool VisitFunctionDecl(FunctionDecl *ND);
295 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000296 bool VisitVarDecl(VarDecl *);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000297 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000298 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor39d6f072010-08-31 19:02:00 +0000299 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000300 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000301 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
302 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
303 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
304 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek23173d72010-05-18 21:09:07 +0000305 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremenek79758f62010-02-18 22:36:18 +0000306 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
307 bool VisitObjCImplDecl(ObjCImplDecl *D);
308 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
309 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000310 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
311 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
312 bool VisitObjCClassDecl(ObjCClassDecl *D);
Ted Kremeneka0536d82010-05-07 01:04:29 +0000313 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenek8f06e0e2010-05-06 23:38:21 +0000314 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregor69319002010-08-31 23:48:11 +0000315 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000316 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregor7e242562010-09-01 19:52:22 +0000317 bool VisitUsingDecl(UsingDecl *D);
318 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
319 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000320
Douglas Gregor01829d32010-08-31 14:41:23 +0000321 // Name visitor
322 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000323 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregor01829d32010-08-31 14:41:23 +0000324
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000325 // Template visitors
326 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregor0b36e612010-08-31 20:37:03 +0000327 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000328 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
329
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000330 // Type visitors
Douglas Gregor01829d32010-08-31 14:41:23 +0000331 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000332 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000333 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000334 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
335 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000336 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000337 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCallc12c5bb2010-05-15 11:32:37 +0000338 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000339 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
340 bool VisitPointerTypeLoc(PointerTypeLoc TL);
341 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
342 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
343 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
344 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor01829d32010-08-31 14:41:23 +0000345 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000346 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000347 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000348 // FIXME: Implement visitors here when the unimplemented TypeLocs get
349 // implemented
350 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
351 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000352
Douglas Gregora59e3902010-01-21 23:27:09 +0000353 // Statement visitors
354 bool VisitStmt(Stmt *S);
355 bool VisitDeclStmt(DeclStmt *S);
Douglas Gregor36897b02010-09-10 00:22:18 +0000356 bool VisitGotoStmt(GotoStmt *S);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000357
Douglas Gregor336fd812010-01-23 00:40:08 +0000358 // Expression visitors
Douglas Gregor8947a752010-09-02 20:35:02 +0000359 bool VisitDeclRefExpr(DeclRefExpr *E);
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000360 bool VisitBlockExpr(BlockExpr *B);
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000361 bool VisitExplicitCastExpr(ExplicitCastExpr *E);
Douglas Gregorc2350e52010-03-08 16:40:19 +0000362 bool VisitObjCMessageExpr(ObjCMessageExpr *E);
Douglas Gregor81d34662010-04-20 15:39:42 +0000363 bool VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Douglas Gregor8ecdb652010-04-28 22:16:22 +0000364 bool VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000365 bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
Douglas Gregor36897b02010-09-10 00:22:18 +0000366 bool VisitAddrLabelExpr(AddrLabelExpr *E);
Douglas Gregor648220e2010-08-10 15:02:34 +0000367 bool VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
368 bool VisitVAArgExpr(VAArgExpr *E);
Douglas Gregorfa2e26f2010-09-09 23:28:23 +0000369 bool VisitDesignatedInitExpr(DesignatedInitExpr *E);
Douglas Gregor94802292010-09-02 21:20:16 +0000370 bool VisitCXXTypeidExpr(CXXTypeidExpr *E);
Douglas Gregor3d37c0a2010-09-09 16:14:44 +0000371 bool VisitCXXUuidofExpr(CXXUuidofExpr *E);
Douglas Gregorda135b12010-09-02 21:38:13 +0000372 bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { return false; }
Douglas Gregorab6677e2010-09-08 00:15:04 +0000373 bool VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
374 bool VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Douglas Gregor1bb2a932010-09-07 21:49:58 +0000375 bool VisitCXXNewExpr(CXXNewExpr *E);
Douglas Gregor6f7198f2010-09-02 22:09:03 +0000376 bool VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Douglas Gregor3d37c0a2010-09-09 16:14:44 +0000377 bool VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Douglas Gregor1f7b5902010-09-02 22:29:21 +0000378 bool VisitOverloadExpr(OverloadExpr *E);
Douglas Gregorbfebed22010-09-03 17:24:10 +0000379 bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Douglas Gregorab6677e2010-09-08 00:15:04 +0000380 bool VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Douglas Gregor25d63622010-09-03 17:35:34 +0000381 bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Douglas Gregoraaa80b22010-09-03 18:01:25 +0000382 bool VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E);
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000383
384#define DATA_RECURSIVE_VISIT(NAME)\
385bool Visit##NAME(NAME *S) { return VisitDataRecursive(S); }
386 DATA_RECURSIVE_VISIT(BinaryOperator)
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000387 DATA_RECURSIVE_VISIT(CompoundLiteralExpr)
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000388 DATA_RECURSIVE_VISIT(CXXMemberCallExpr)
Ted Kremenek8c269ac2010-11-11 23:11:43 +0000389 DATA_RECURSIVE_VISIT(CXXOperatorCallExpr)
Ted Kremenekbb677132010-11-12 18:27:04 +0000390 DATA_RECURSIVE_VISIT(DoStmt)
Ted Kremenekc70ebba2010-11-12 18:26:58 +0000391 DATA_RECURSIVE_VISIT(IfStmt)
Ted Kremeneka6b70432010-11-12 21:34:09 +0000392 DATA_RECURSIVE_VISIT(InitListExpr)
Ted Kremenekbb677132010-11-12 18:27:04 +0000393 DATA_RECURSIVE_VISIT(ForStmt)
Ted Kremenekc70ebba2010-11-12 18:26:58 +0000394 DATA_RECURSIVE_VISIT(MemberExpr)
Ted Kremenekf1107452010-11-12 18:26:56 +0000395 DATA_RECURSIVE_VISIT(SwitchStmt)
Ted Kremenekbb677132010-11-12 18:27:04 +0000396 DATA_RECURSIVE_VISIT(WhileStmt)
Ted Kremeneka6b70432010-11-12 21:34:09 +0000397
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000398 // Data-recursive visitor functions.
399 bool IsInRegionOfInterest(CXCursor C);
400 bool RunVisitorWorkList(VisitorWorkList &WL);
401 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
402 bool VisitDataRecursive(Stmt *S);
Steve Naroff89922f82009-08-31 00:59:03 +0000403};
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000404
Ted Kremenekab188932010-01-05 19:32:54 +0000405} // end anonymous namespace
Benjamin Kramer5e4bc592009-10-18 16:11:04 +0000406
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000407static SourceRange getRawCursorExtent(CXCursor C);
408
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000409RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000410 return RangeCompare(TU->getSourceManager(), R, RegionOfInterest);
411}
412
Douglas Gregorb1373d02010-01-20 20:59:29 +0000413/// \brief Visit the given cursor and, if requested by the visitor,
414/// its children.
415///
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000416/// \param Cursor the cursor to visit.
417///
418/// \param CheckRegionOfInterest if true, then the caller already checked that
419/// this cursor is within the region of interest.
420///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000421/// \returns true if the visitation should be aborted, false if it
422/// should continue.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000423bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregorb1373d02010-01-20 20:59:29 +0000424 if (clang_isInvalid(Cursor.kind))
425 return false;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000426
Douglas Gregorb1373d02010-01-20 20:59:29 +0000427 if (clang_isDeclaration(Cursor.kind)) {
428 Decl *D = getCursorDecl(Cursor);
429 assert(D && "Invalid declaration cursor");
430 if (D->getPCHLevel() > MaxPCHLevel)
431 return false;
432
433 if (D->isImplicit())
434 return false;
435 }
436
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000437 // If we have a range of interest, and this cursor doesn't intersect with it,
438 // we're done.
439 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000440 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbarf408f322010-02-14 08:32:05 +0000441 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000442 return false;
443 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000444
Douglas Gregorb1373d02010-01-20 20:59:29 +0000445 switch (Visitor(Cursor, Parent, ClientData)) {
446 case CXChildVisit_Break:
447 return true;
448
449 case CXChildVisit_Continue:
450 return false;
451
452 case CXChildVisit_Recurse:
453 return VisitChildren(Cursor);
454 }
455
Douglas Gregorfd643772010-01-25 16:45:46 +0000456 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000457}
458
Douglas Gregor788f5a12010-03-20 00:41:21 +0000459std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
460CursorVisitor::getPreprocessedEntities() {
461 PreprocessingRecord &PPRec
462 = *TU->getPreprocessor().getPreprocessingRecord();
463
464 bool OnlyLocalDecls
465 = !TU->isMainFileAST() && TU->getOnlyLocalDecls();
466
467 // There is no region of interest; we have to walk everything.
468 if (RegionOfInterest.isInvalid())
469 return std::make_pair(PPRec.begin(OnlyLocalDecls),
470 PPRec.end(OnlyLocalDecls));
471
472 // Find the file in which the region of interest lands.
473 SourceManager &SM = TU->getSourceManager();
474 std::pair<FileID, unsigned> Begin
475 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
476 std::pair<FileID, unsigned> End
477 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
478
479 // The region of interest spans files; we have to walk everything.
480 if (Begin.first != End.first)
481 return std::make_pair(PPRec.begin(OnlyLocalDecls),
482 PPRec.end(OnlyLocalDecls));
483
484 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
485 = TU->getPreprocessedEntitiesByFile();
486 if (ByFileMap.empty()) {
487 // Build the mapping from files to sets of preprocessed entities.
488 for (PreprocessingRecord::iterator E = PPRec.begin(OnlyLocalDecls),
489 EEnd = PPRec.end(OnlyLocalDecls);
490 E != EEnd; ++E) {
491 std::pair<FileID, unsigned> P
492 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
493 ByFileMap[P.first].push_back(*E);
494 }
495 }
496
497 return std::make_pair(ByFileMap[Begin.first].begin(),
498 ByFileMap[Begin.first].end());
499}
500
Douglas Gregorb1373d02010-01-20 20:59:29 +0000501/// \brief Visit the children of the given cursor.
502///
503/// \returns true if the visitation should be aborted, false if it
504/// should continue.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000505bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregora59e3902010-01-21 23:27:09 +0000506 if (clang_isReference(Cursor.kind)) {
507 // By definition, references have no children.
508 return false;
509 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000510
511 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregorb1373d02010-01-20 20:59:29 +0000512 // done.
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000513 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000514
Douglas Gregorb1373d02010-01-20 20:59:29 +0000515 if (clang_isDeclaration(Cursor.kind)) {
516 Decl *D = getCursorDecl(Cursor);
517 assert(D && "Invalid declaration cursor");
Ted Kremenek539311e2010-02-18 18:47:01 +0000518 return VisitAttributes(D) || Visit(D);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000519 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000520
Douglas Gregora59e3902010-01-21 23:27:09 +0000521 if (clang_isStatement(Cursor.kind))
522 return Visit(getCursorStmt(Cursor));
523 if (clang_isExpression(Cursor.kind))
524 return Visit(getCursorExpr(Cursor));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000525
Douglas Gregorb1373d02010-01-20 20:59:29 +0000526 if (clang_isTranslationUnit(Cursor.kind)) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000527 ASTUnit *CXXUnit = getCursorASTUnit(Cursor);
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000528 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
529 RegionOfInterest.isInvalid()) {
Douglas Gregoreb8837b2010-08-03 19:06:41 +0000530 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
531 TLEnd = CXXUnit->top_level_end();
532 TL != TLEnd; ++TL) {
533 if (Visit(MakeCXCursor(*TL, CXXUnit), true))
Douglas Gregor7b691f332010-01-20 21:13:59 +0000534 return true;
535 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000536 } else if (VisitDeclContext(
537 CXXUnit->getASTContext().getTranslationUnitDecl()))
538 return true;
Bob Wilson3178cb62010-03-19 03:57:57 +0000539
Douglas Gregor0396f462010-03-19 05:22:59 +0000540 // Walk the preprocessing record.
Daniel Dunbar8de30ff2010-03-20 01:11:56 +0000541 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
Douglas Gregor0396f462010-03-19 05:22:59 +0000542 // FIXME: Once we have the ability to deserialize a preprocessing record,
543 // do so.
Douglas Gregor788f5a12010-03-20 00:41:21 +0000544 PreprocessingRecord::iterator E, EEnd;
545 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
Douglas Gregor0396f462010-03-19 05:22:59 +0000546 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
547 if (Visit(MakeMacroInstantiationCursor(MI, CXXUnit)))
548 return true;
Douglas Gregor788f5a12010-03-20 00:41:21 +0000549
Douglas Gregor0396f462010-03-19 05:22:59 +0000550 continue;
551 }
552
553 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
554 if (Visit(MakeMacroDefinitionCursor(MD, CXXUnit)))
555 return true;
556
557 continue;
558 }
Douglas Gregorecdcb882010-10-20 22:00:55 +0000559
560 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
561 if (Visit(MakeInclusionDirectiveCursor(ID, CXXUnit)))
562 return true;
563
564 continue;
565 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000566 }
567 }
Douglas Gregor7b691f332010-01-20 21:13:59 +0000568 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000569 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000570
Douglas Gregorb1373d02010-01-20 20:59:29 +0000571 // Nothing to visit at the moment.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000572 return false;
573}
574
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000575bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
John McCallfc929202010-06-04 22:33:30 +0000576 if (Visit(B->getSignatureAsWritten()->getTypeLoc()))
577 return true;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000578
Ted Kremenek664cffd2010-07-22 11:30:19 +0000579 if (Stmt *Body = B->getBody())
580 return Visit(MakeCXCursor(Body, StmtParent, TU));
581
582 return false;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000583}
584
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000585llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
586 if (RegionOfInterest.isValid()) {
587 SourceRange Range = getRawCursorExtent(Cursor);
588 if (Range.isInvalid())
589 return llvm::Optional<bool>();
Ted Kremenek09dfa372010-02-18 05:46:33 +0000590
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000591 switch (CompareRegionOfInterest(Range)) {
592 case RangeBefore:
593 // This declaration comes before the region of interest; skip it.
594 return llvm::Optional<bool>();
595
596 case RangeAfter:
597 // This declaration comes after the region of interest; we're done.
598 return false;
599
600 case RangeOverlap:
601 // This declaration overlaps the region of interest; visit it.
602 break;
603 }
604 }
605 return true;
606}
607
608bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
609 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
610
611 // FIXME: Eventually remove. This part of a hack to support proper
612 // iteration over all Decls contained lexically within an ObjC container.
613 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
614 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
615
616 for ( ; I != E; ++I) {
Ted Kremenek23173d72010-05-18 21:09:07 +0000617 Decl *D = *I;
618 if (D->getLexicalDeclContext() != DC)
619 continue;
Ted Kremenek23173d72010-05-18 21:09:07 +0000620 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000621 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
622 if (!V.hasValue())
623 continue;
624 if (!V.getValue())
625 return false;
Daniel Dunbard52864b2010-02-14 10:02:57 +0000626 if (Visit(Cursor, true))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000627 return true;
628 }
Douglas Gregorb1373d02010-01-20 20:59:29 +0000629 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000630}
631
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000632bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
633 llvm_unreachable("Translation units are visited directly by Visit()");
634 return false;
635}
636
637bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
638 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
639 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000640
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000641 return false;
642}
643
644bool CursorVisitor::VisitTagDecl(TagDecl *D) {
645 return VisitDeclContext(D);
646}
647
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000648bool CursorVisitor::VisitClassTemplateSpecializationDecl(
649 ClassTemplateSpecializationDecl *D) {
650 bool ShouldVisitBody = false;
651 switch (D->getSpecializationKind()) {
652 case TSK_Undeclared:
653 case TSK_ImplicitInstantiation:
654 // Nothing to visit
655 return false;
656
657 case TSK_ExplicitInstantiationDeclaration:
658 case TSK_ExplicitInstantiationDefinition:
659 break;
660
661 case TSK_ExplicitSpecialization:
662 ShouldVisitBody = true;
663 break;
664 }
665
666 // Visit the template arguments used in the specialization.
667 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
668 TypeLoc TL = SpecType->getTypeLoc();
669 if (TemplateSpecializationTypeLoc *TSTLoc
670 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
671 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
672 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
673 return true;
674 }
675 }
676
677 if (ShouldVisitBody && VisitCXXRecordDecl(D))
678 return true;
679
680 return false;
681}
682
Douglas Gregor74dbe642010-08-31 19:31:58 +0000683bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
684 ClassTemplatePartialSpecializationDecl *D) {
685 // FIXME: Visit the "outer" template parameter lists on the TagDecl
686 // before visiting these template parameters.
687 if (VisitTemplateParameters(D->getTemplateParameters()))
688 return true;
689
690 // Visit the partial specialization arguments.
691 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
692 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
693 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
694 return true;
695
696 return VisitCXXRecordDecl(D);
697}
698
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000699bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor84b51d72010-09-01 20:16:53 +0000700 // Visit the default argument.
701 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
702 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
703 if (Visit(DefArg->getTypeLoc()))
704 return true;
705
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000706 return false;
707}
708
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000709bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
710 if (Expr *Init = D->getInitExpr())
711 return Visit(MakeCXCursor(Init, StmtParent, TU));
712 return false;
713}
714
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000715bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
716 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
717 if (Visit(TSInfo->getTypeLoc()))
718 return true;
719
720 return false;
721}
722
Douglas Gregora67e03f2010-09-09 21:42:20 +0000723/// \brief Compare two base or member initializers based on their source order.
724static int CompareCXXBaseOrMemberInitializers(const void* Xp, const void *Yp) {
725 CXXBaseOrMemberInitializer const * const *X
726 = static_cast<CXXBaseOrMemberInitializer const * const *>(Xp);
727 CXXBaseOrMemberInitializer const * const *Y
728 = static_cast<CXXBaseOrMemberInitializer const * const *>(Yp);
729
730 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
731 return -1;
732 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
733 return 1;
734 else
735 return 0;
736}
737
Douglas Gregorb1373d02010-01-20 20:59:29 +0000738bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor01829d32010-08-31 14:41:23 +0000739 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
740 // Visit the function declaration's syntactic components in the order
741 // written. This requires a bit of work.
742 TypeLoc TL = TSInfo->getTypeLoc();
743 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
744
745 // If we have a function declared directly (without the use of a typedef),
746 // visit just the return type. Otherwise, just visit the function's type
747 // now.
748 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
749 (!FTL && Visit(TL)))
750 return true;
751
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000752 // Visit the nested-name-specifier, if present.
753 if (NestedNameSpecifier *Qualifier = ND->getQualifier())
754 if (VisitNestedNameSpecifier(Qualifier, ND->getQualifierRange()))
755 return true;
Douglas Gregor01829d32010-08-31 14:41:23 +0000756
757 // Visit the declaration name.
758 if (VisitDeclarationNameInfo(ND->getNameInfo()))
759 return true;
760
761 // FIXME: Visit explicitly-specified template arguments!
762
763 // Visit the function parameters, if we have a function type.
764 if (FTL && VisitFunctionTypeLoc(*FTL, true))
765 return true;
766
767 // FIXME: Attributes?
768 }
769
Douglas Gregora67e03f2010-09-09 21:42:20 +0000770 if (ND->isThisDeclarationADefinition()) {
771 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
772 // Find the initializers that were written in the source.
773 llvm::SmallVector<CXXBaseOrMemberInitializer *, 4> WrittenInits;
774 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
775 IEnd = Constructor->init_end();
776 I != IEnd; ++I) {
777 if (!(*I)->isWritten())
778 continue;
779
780 WrittenInits.push_back(*I);
781 }
782
783 // Sort the initializers in source order
784 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
785 &CompareCXXBaseOrMemberInitializers);
786
787 // Visit the initializers in source order
788 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
789 CXXBaseOrMemberInitializer *Init = WrittenInits[I];
790 if (Init->isMemberInitializer()) {
791 if (Visit(MakeCursorMemberRef(Init->getMember(),
792 Init->getMemberLocation(), TU)))
793 return true;
794 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
795 if (Visit(BaseInfo->getTypeLoc()))
796 return true;
797 }
798
799 // Visit the initializer value.
800 if (Expr *Initializer = Init->getInit())
801 if (Visit(MakeCXCursor(Initializer, ND, TU)))
802 return true;
803 }
804 }
805
806 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
807 return true;
808 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000809
Douglas Gregorb1373d02010-01-20 20:59:29 +0000810 return false;
811}
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000812
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000813bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
814 if (VisitDeclaratorDecl(D))
815 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000816
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000817 if (Expr *BitWidth = D->getBitWidth())
818 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000819
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000820 return false;
821}
822
823bool CursorVisitor::VisitVarDecl(VarDecl *D) {
824 if (VisitDeclaratorDecl(D))
825 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000826
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000827 if (Expr *Init = D->getInit())
828 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000829
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000830 return false;
831}
832
Douglas Gregor84b51d72010-09-01 20:16:53 +0000833bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
834 if (VisitDeclaratorDecl(D))
835 return true;
836
837 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
838 if (Expr *DefArg = D->getDefaultArgument())
839 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
840
841 return false;
842}
843
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000844bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
845 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
846 // before visiting these template parameters.
847 if (VisitTemplateParameters(D->getTemplateParameters()))
848 return true;
849
850 return VisitFunctionDecl(D->getTemplatedDecl());
851}
852
Douglas Gregor39d6f072010-08-31 19:02:00 +0000853bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
854 // FIXME: Visit the "outer" template parameter lists on the TagDecl
855 // before visiting these template parameters.
856 if (VisitTemplateParameters(D->getTemplateParameters()))
857 return true;
858
859 return VisitCXXRecordDecl(D->getTemplatedDecl());
860}
861
Douglas Gregor84b51d72010-09-01 20:16:53 +0000862bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
863 if (VisitTemplateParameters(D->getTemplateParameters()))
864 return true;
865
866 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
867 VisitTemplateArgumentLoc(D->getDefaultArgument()))
868 return true;
869
870 return false;
871}
872
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000873bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor4bc1cb62010-03-08 14:59:44 +0000874 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
875 if (Visit(TSInfo->getTypeLoc()))
876 return true;
877
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000878 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000879 PEnd = ND->param_end();
880 P != PEnd; ++P) {
881 if (Visit(MakeCXCursor(*P, TU)))
882 return true;
883 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000884
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000885 if (ND->isThisDeclarationADefinition() &&
886 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
887 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000888
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000889 return false;
890}
891
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000892namespace {
893 struct ContainerDeclsSort {
894 SourceManager &SM;
895 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
896 bool operator()(Decl *A, Decl *B) {
897 SourceLocation L_A = A->getLocStart();
898 SourceLocation L_B = B->getLocStart();
899 assert(L_A.isValid() && L_B.isValid());
900 return SM.isBeforeInTranslationUnit(L_A, L_B);
901 }
902 };
903}
904
Douglas Gregora59e3902010-01-21 23:27:09 +0000905bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000906 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
907 // an @implementation can lexically contain Decls that are not properly
908 // nested in the AST. When we identify such cases, we need to retrofit
909 // this nesting here.
910 if (!DI_current)
911 return VisitDeclContext(D);
912
913 // Scan the Decls that immediately come after the container
914 // in the current DeclContext. If any fall within the
915 // container's lexical region, stash them into a vector
916 // for later processing.
917 llvm::SmallVector<Decl *, 24> DeclsInContainer;
918 SourceLocation EndLoc = D->getSourceRange().getEnd();
919 SourceManager &SM = TU->getSourceManager();
920 if (EndLoc.isValid()) {
921 DeclContext::decl_iterator next = *DI_current;
922 while (++next != DE_current) {
923 Decl *D_next = *next;
924 if (!D_next)
925 break;
926 SourceLocation L = D_next->getLocStart();
927 if (!L.isValid())
928 break;
929 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
930 *DI_current = next;
931 DeclsInContainer.push_back(D_next);
932 continue;
933 }
934 break;
935 }
936 }
937
938 // The common case.
939 if (DeclsInContainer.empty())
940 return VisitDeclContext(D);
941
942 // Get all the Decls in the DeclContext, and sort them with the
943 // additional ones we've collected. Then visit them.
944 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
945 I!=E; ++I) {
946 Decl *subDecl = *I;
Ted Kremenek0582c892010-11-02 23:17:51 +0000947 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
948 subDecl->getLocStart().isInvalid())
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000949 continue;
950 DeclsInContainer.push_back(subDecl);
951 }
952
953 // Now sort the Decls so that they appear in lexical order.
954 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
955 ContainerDeclsSort(SM));
956
957 // Now visit the decls.
958 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
959 E = DeclsInContainer.end(); I != E; ++I) {
960 CXCursor Cursor = MakeCXCursor(*I, TU);
961 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
962 if (!V.hasValue())
963 continue;
964 if (!V.getValue())
965 return false;
966 if (Visit(Cursor, true))
967 return true;
968 }
969 return false;
Douglas Gregora59e3902010-01-21 23:27:09 +0000970}
971
Douglas Gregorb1373d02010-01-20 20:59:29 +0000972bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000973 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
974 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000975 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000976
Douglas Gregor78db0cd2010-01-16 15:44:18 +0000977 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
978 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
979 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000980 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000981 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000982
Douglas Gregora59e3902010-01-21 23:27:09 +0000983 return VisitObjCContainerDecl(ND);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000984}
985
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000986bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
987 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
988 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
989 E = PID->protocol_end(); I != E; ++I, ++PL)
990 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
991 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000992
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000993 return VisitObjCContainerDecl(PID);
994}
995
Ted Kremenek23173d72010-05-18 21:09:07 +0000996bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor83cb9422010-09-09 17:09:21 +0000997 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCallfc929202010-06-04 22:33:30 +0000998 return true;
999
Ted Kremenek23173d72010-05-18 21:09:07 +00001000 // FIXME: This implements a workaround with @property declarations also being
1001 // installed in the DeclContext for the @interface. Eventually this code
1002 // should be removed.
1003 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1004 if (!CDecl || !CDecl->IsClassExtension())
1005 return false;
1006
1007 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1008 if (!ID)
1009 return false;
1010
1011 IdentifierInfo *PropertyId = PD->getIdentifier();
1012 ObjCPropertyDecl *prevDecl =
1013 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1014
1015 if (!prevDecl)
1016 return false;
1017
1018 // Visit synthesized methods since they will be skipped when visiting
1019 // the @interface.
1020 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001021 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001022 if (Visit(MakeCXCursor(MD, TU)))
1023 return true;
1024
1025 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001026 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001027 if (Visit(MakeCXCursor(MD, TU)))
1028 return true;
1029
1030 return false;
1031}
1032
Douglas Gregorb1373d02010-01-20 20:59:29 +00001033bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001034 // Issue callbacks for super class.
Douglas Gregorb1373d02010-01-20 20:59:29 +00001035 if (D->getSuperClass() &&
1036 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001037 D->getSuperClassLoc(),
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001038 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001039 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001040
Douglas Gregor78db0cd2010-01-16 15:44:18 +00001041 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1042 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1043 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001044 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001045 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001046
Douglas Gregora59e3902010-01-21 23:27:09 +00001047 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001048}
1049
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001050bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1051 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001052}
1053
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001054bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremenekebfa3392010-03-19 20:39:03 +00001055 // 'ID' could be null when dealing with invalid code.
1056 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1057 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1058 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001059
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001060 return VisitObjCImplDecl(D);
1061}
1062
1063bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1064#if 0
1065 // Issue callbacks for super class.
1066 // FIXME: No source location information!
1067 if (D->getSuperClass() &&
1068 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001069 D->getSuperClassLoc(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001070 TU)))
1071 return true;
1072#endif
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001073
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001074 return VisitObjCImplDecl(D);
1075}
1076
1077bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1078 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1079 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1080 E = D->protocol_end();
1081 I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001082 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001083 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001084
1085 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001086}
1087
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001088bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1089 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1090 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1091 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001092
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001093 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001094}
1095
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00001096bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1097 return VisitDeclContext(D);
1098}
1099
Douglas Gregor69319002010-08-31 23:48:11 +00001100bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001101 // Visit nested-name-specifier.
1102 if (NestedNameSpecifier *Qualifier = D->getQualifier())
1103 if (VisitNestedNameSpecifier(Qualifier, D->getQualifierRange()))
1104 return true;
Douglas Gregor69319002010-08-31 23:48:11 +00001105
1106 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1107 D->getTargetNameLoc(), TU));
1108}
1109
Douglas Gregor7e242562010-09-01 19:52:22 +00001110bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001111 // Visit nested-name-specifier.
1112 if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameDecl())
1113 if (VisitNestedNameSpecifier(Qualifier, D->getNestedNameRange()))
1114 return true;
Douglas Gregor7e242562010-09-01 19:52:22 +00001115
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001116 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1117 return true;
1118
Douglas Gregor7e242562010-09-01 19:52:22 +00001119 return VisitDeclarationNameInfo(D->getNameInfo());
1120}
1121
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001122bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001123 // Visit nested-name-specifier.
1124 if (NestedNameSpecifier *Qualifier = D->getQualifier())
1125 if (VisitNestedNameSpecifier(Qualifier, D->getQualifierRange()))
1126 return true;
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001127
1128 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1129 D->getIdentLocation(), TU));
1130}
1131
Douglas Gregor7e242562010-09-01 19:52:22 +00001132bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001133 // Visit nested-name-specifier.
1134 if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier())
1135 if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange()))
1136 return true;
1137
Douglas Gregor7e242562010-09-01 19:52:22 +00001138 return VisitDeclarationNameInfo(D->getNameInfo());
1139}
1140
1141bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1142 UnresolvedUsingTypenameDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001143 // Visit nested-name-specifier.
1144 if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier())
1145 if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange()))
1146 return true;
1147
Douglas Gregor7e242562010-09-01 19:52:22 +00001148 return false;
1149}
1150
Douglas Gregor01829d32010-08-31 14:41:23 +00001151bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1152 switch (Name.getName().getNameKind()) {
1153 case clang::DeclarationName::Identifier:
1154 case clang::DeclarationName::CXXLiteralOperatorName:
1155 case clang::DeclarationName::CXXOperatorName:
1156 case clang::DeclarationName::CXXUsingDirective:
1157 return false;
1158
1159 case clang::DeclarationName::CXXConstructorName:
1160 case clang::DeclarationName::CXXDestructorName:
1161 case clang::DeclarationName::CXXConversionFunctionName:
1162 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1163 return Visit(TSInfo->getTypeLoc());
1164 return false;
1165
1166 case clang::DeclarationName::ObjCZeroArgSelector:
1167 case clang::DeclarationName::ObjCOneArgSelector:
1168 case clang::DeclarationName::ObjCMultiArgSelector:
1169 // FIXME: Per-identifier location info?
1170 return false;
1171 }
1172
1173 return false;
1174}
1175
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001176bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1177 SourceRange Range) {
1178 // FIXME: This whole routine is a hack to work around the lack of proper
1179 // source information in nested-name-specifiers (PR5791). Since we do have
1180 // a beginning source location, we can visit the first component of the
1181 // nested-name-specifier, if it's a single-token component.
1182 if (!NNS)
1183 return false;
1184
1185 // Get the first component in the nested-name-specifier.
1186 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1187 NNS = Prefix;
1188
1189 switch (NNS->getKind()) {
1190 case NestedNameSpecifier::Namespace:
1191 // FIXME: The token at this source location might actually have been a
1192 // namespace alias, but we don't model that. Lame!
1193 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1194 TU));
1195
1196 case NestedNameSpecifier::TypeSpec: {
1197 // If the type has a form where we know that the beginning of the source
1198 // range matches up with a reference cursor. Visit the appropriate reference
1199 // cursor.
1200 Type *T = NNS->getAsType();
1201 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1202 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1203 if (const TagType *Tag = dyn_cast<TagType>(T))
1204 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1205 if (const TemplateSpecializationType *TST
1206 = dyn_cast<TemplateSpecializationType>(T))
1207 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1208 break;
1209 }
1210
1211 case NestedNameSpecifier::TypeSpecWithTemplate:
1212 case NestedNameSpecifier::Global:
1213 case NestedNameSpecifier::Identifier:
1214 break;
1215 }
1216
1217 return false;
1218}
1219
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001220bool CursorVisitor::VisitTemplateParameters(
1221 const TemplateParameterList *Params) {
1222 if (!Params)
1223 return false;
1224
1225 for (TemplateParameterList::const_iterator P = Params->begin(),
1226 PEnd = Params->end();
1227 P != PEnd; ++P) {
1228 if (Visit(MakeCXCursor(*P, TU)))
1229 return true;
1230 }
1231
1232 return false;
1233}
1234
Douglas Gregor0b36e612010-08-31 20:37:03 +00001235bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1236 switch (Name.getKind()) {
1237 case TemplateName::Template:
1238 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1239
1240 case TemplateName::OverloadedTemplate:
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001241 // Visit the overloaded template set.
1242 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1243 return true;
1244
Douglas Gregor0b36e612010-08-31 20:37:03 +00001245 return false;
1246
1247 case TemplateName::DependentTemplate:
1248 // FIXME: Visit nested-name-specifier.
1249 return false;
1250
1251 case TemplateName::QualifiedTemplate:
1252 // FIXME: Visit nested-name-specifier.
1253 return Visit(MakeCursorTemplateRef(
1254 Name.getAsQualifiedTemplateName()->getDecl(),
1255 Loc, TU));
1256 }
1257
1258 return false;
1259}
1260
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001261bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1262 switch (TAL.getArgument().getKind()) {
1263 case TemplateArgument::Null:
1264 case TemplateArgument::Integral:
1265 return false;
1266
1267 case TemplateArgument::Pack:
1268 // FIXME: Implement when variadic templates come along.
1269 return false;
1270
1271 case TemplateArgument::Type:
1272 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1273 return Visit(TSInfo->getTypeLoc());
1274 return false;
1275
1276 case TemplateArgument::Declaration:
1277 if (Expr *E = TAL.getSourceDeclExpression())
1278 return Visit(MakeCXCursor(E, StmtParent, TU));
1279 return false;
1280
1281 case TemplateArgument::Expression:
1282 if (Expr *E = TAL.getSourceExpression())
1283 return Visit(MakeCXCursor(E, StmtParent, TU));
1284 return false;
1285
1286 case TemplateArgument::Template:
Douglas Gregor0b36e612010-08-31 20:37:03 +00001287 return VisitTemplateName(TAL.getArgument().getAsTemplate(),
1288 TAL.getTemplateNameLoc());
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001289 }
1290
1291 return false;
1292}
1293
Ted Kremeneka0536d82010-05-07 01:04:29 +00001294bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1295 return VisitDeclContext(D);
1296}
1297
Douglas Gregor01829d32010-08-31 14:41:23 +00001298bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1299 return Visit(TL.getUnqualifiedLoc());
1300}
1301
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001302bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1303 ASTContext &Context = TU->getASTContext();
1304
1305 // Some builtin types (such as Objective-C's "id", "sel", and
1306 // "Class") have associated declarations. Create cursors for those.
1307 QualType VisitType;
1308 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001309 case BuiltinType::Void:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001310 case BuiltinType::Bool:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001311 case BuiltinType::Char_U:
1312 case BuiltinType::UChar:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001313 case BuiltinType::Char16:
1314 case BuiltinType::Char32:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001315 case BuiltinType::UShort:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001316 case BuiltinType::UInt:
1317 case BuiltinType::ULong:
1318 case BuiltinType::ULongLong:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001319 case BuiltinType::UInt128:
1320 case BuiltinType::Char_S:
1321 case BuiltinType::SChar:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001322 case BuiltinType::WChar:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001323 case BuiltinType::Short:
1324 case BuiltinType::Int:
1325 case BuiltinType::Long:
1326 case BuiltinType::LongLong:
1327 case BuiltinType::Int128:
1328 case BuiltinType::Float:
1329 case BuiltinType::Double:
1330 case BuiltinType::LongDouble:
1331 case BuiltinType::NullPtr:
1332 case BuiltinType::Overload:
1333 case BuiltinType::Dependent:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001334 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001335
1336 case BuiltinType::UndeducedAuto: // FIXME: Deserves a cursor?
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001337 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001338
Ted Kremenekc4174cc2010-02-18 18:52:18 +00001339 case BuiltinType::ObjCId:
1340 VisitType = Context.getObjCIdType();
1341 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001342
1343 case BuiltinType::ObjCClass:
1344 VisitType = Context.getObjCClassType();
1345 break;
1346
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001347 case BuiltinType::ObjCSel:
1348 VisitType = Context.getObjCSelType();
1349 break;
1350 }
1351
1352 if (!VisitType.isNull()) {
1353 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001354 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001355 TU));
1356 }
1357
1358 return false;
1359}
1360
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001361bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1362 return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
1363}
1364
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001365bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1366 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1367}
1368
1369bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1370 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1371}
1372
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001373bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001374 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001375 // no context information with which we can match up the depth/index in the
1376 // type to the appropriate
1377 return false;
1378}
1379
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001380bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1381 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1382 return true;
1383
John McCallc12c5bb2010-05-15 11:32:37 +00001384 return false;
1385}
1386
1387bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1388 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1389 return true;
1390
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001391 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1392 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1393 TU)))
1394 return true;
1395 }
1396
1397 return false;
1398}
1399
1400bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCallc12c5bb2010-05-15 11:32:37 +00001401 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001402}
1403
1404bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1405 return Visit(TL.getPointeeLoc());
1406}
1407
1408bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1409 return Visit(TL.getPointeeLoc());
1410}
1411
1412bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1413 return Visit(TL.getPointeeLoc());
1414}
1415
1416bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001417 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001418}
1419
1420bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001421 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001422}
1423
Douglas Gregor01829d32010-08-31 14:41:23 +00001424bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1425 bool SkipResultType) {
1426 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001427 return true;
1428
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001429 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek5dbacb42010-04-07 00:27:13 +00001430 if (Decl *D = TL.getArg(I))
1431 if (Visit(MakeCXCursor(D, TU)))
1432 return true;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001433
1434 return false;
1435}
1436
1437bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1438 if (Visit(TL.getElementLoc()))
1439 return true;
1440
1441 if (Expr *Size = TL.getSizeExpr())
1442 return Visit(MakeCXCursor(Size, StmtParent, TU));
1443
1444 return false;
1445}
1446
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001447bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1448 TemplateSpecializationTypeLoc TL) {
Douglas Gregor0b36e612010-08-31 20:37:03 +00001449 // Visit the template name.
1450 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1451 TL.getTemplateNameLoc()))
1452 return true;
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001453
1454 // Visit the template arguments.
1455 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1456 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1457 return true;
1458
1459 return false;
1460}
1461
Douglas Gregor2332c112010-01-21 20:48:56 +00001462bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1463 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1464}
1465
1466bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1467 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1468 return Visit(TSInfo->getTypeLoc());
1469
1470 return false;
1471}
1472
Douglas Gregora59e3902010-01-21 23:27:09 +00001473bool CursorVisitor::VisitStmt(Stmt *S) {
1474 for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end();
1475 Child != ChildEnd; ++Child) {
Ted Kremenek0f91f6a2010-05-13 00:25:00 +00001476 if (Stmt *C = *Child)
1477 if (Visit(MakeCXCursor(C, StmtParent, TU)))
1478 return true;
Douglas Gregora59e3902010-01-21 23:27:09 +00001479 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001480
Douglas Gregora59e3902010-01-21 23:27:09 +00001481 return false;
1482}
1483
1484bool CursorVisitor::VisitDeclStmt(DeclStmt *S) {
Ted Kremenek007a7c92010-11-01 23:26:51 +00001485 bool isFirst = true;
Douglas Gregora59e3902010-01-21 23:27:09 +00001486 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1487 D != DEnd; ++D) {
Ted Kremenek007a7c92010-11-01 23:26:51 +00001488 if (*D && Visit(MakeCXCursor(*D, TU, isFirst)))
Douglas Gregora59e3902010-01-21 23:27:09 +00001489 return true;
Ted Kremenek007a7c92010-11-01 23:26:51 +00001490 isFirst = false;
Douglas Gregora59e3902010-01-21 23:27:09 +00001491 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001492
Douglas Gregora59e3902010-01-21 23:27:09 +00001493 return false;
1494}
1495
Douglas Gregor36897b02010-09-10 00:22:18 +00001496bool CursorVisitor::VisitGotoStmt(GotoStmt *S) {
1497 return Visit(MakeCursorLabelRef(S->getLabel(), S->getLabelLoc(), TU));
1498}
1499
Douglas Gregor8947a752010-09-02 20:35:02 +00001500bool CursorVisitor::VisitDeclRefExpr(DeclRefExpr *E) {
1501 // Visit nested-name-specifier, if present.
1502 if (NestedNameSpecifier *Qualifier = E->getQualifier())
1503 if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange()))
1504 return true;
1505
1506 // Visit declaration name.
1507 if (VisitDeclarationNameInfo(E->getNameInfo()))
1508 return true;
1509
1510 // Visit explicitly-specified template arguments.
1511 if (E->hasExplicitTemplateArgs()) {
1512 ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
1513 for (TemplateArgumentLoc *Arg = Args.getTemplateArgs(),
1514 *ArgEnd = Arg + Args.NumTemplateArgs;
1515 Arg != ArgEnd; ++Arg)
1516 if (VisitTemplateArgumentLoc(*Arg))
1517 return true;
1518 }
1519
1520 return false;
1521}
1522
Ted Kremenek3064ef92010-08-27 21:34:58 +00001523bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1524 if (D->isDefinition()) {
1525 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1526 E = D->bases_end(); I != E; ++I) {
1527 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1528 return true;
1529 }
1530 }
1531
1532 return VisitTagDecl(D);
1533}
1534
1535
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00001536bool CursorVisitor::VisitBlockExpr(BlockExpr *B) {
1537 return Visit(B->getBlockDecl());
1538}
1539
Douglas Gregor8ecdb652010-04-28 22:16:22 +00001540bool CursorVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
Douglas Gregor8ccef2d2010-09-09 23:10:46 +00001541 // Visit the type into which we're computing an offset.
Douglas Gregor8ecdb652010-04-28 22:16:22 +00001542 if (Visit(E->getTypeSourceInfo()->getTypeLoc()))
1543 return true;
Douglas Gregor8ccef2d2010-09-09 23:10:46 +00001544
1545 // Visit the components of the offsetof expression.
1546 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
1547 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
1548 const OffsetOfNode &Node = E->getComponent(I);
1549 switch (Node.getKind()) {
1550 case OffsetOfNode::Array:
1551 if (Visit(MakeCXCursor(E->getIndexExpr(Node.getArrayExprIndex()),
1552 StmtParent, TU)))
1553 return true;
1554 break;
1555
1556 case OffsetOfNode::Field:
1557 if (Visit(MakeCursorMemberRef(Node.getField(), Node.getRange().getEnd(),
1558 TU)))
1559 return true;
1560 break;
1561
1562 case OffsetOfNode::Identifier:
1563 case OffsetOfNode::Base:
1564 continue;
1565 }
1566 }
Douglas Gregor8ecdb652010-04-28 22:16:22 +00001567
Douglas Gregor8ccef2d2010-09-09 23:10:46 +00001568 return false;
Douglas Gregor8ecdb652010-04-28 22:16:22 +00001569}
1570
Douglas Gregor336fd812010-01-23 00:40:08 +00001571bool CursorVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
1572 if (E->isArgumentType()) {
1573 if (TypeSourceInfo *TSInfo = E->getArgumentTypeInfo())
1574 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001575
Douglas Gregor336fd812010-01-23 00:40:08 +00001576 return false;
1577 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001578
Douglas Gregor336fd812010-01-23 00:40:08 +00001579 return VisitExpr(E);
1580}
1581
1582bool CursorVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1583 if (TypeSourceInfo *TSInfo = E->getTypeInfoAsWritten())
1584 if (Visit(TSInfo->getTypeLoc()))
1585 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001586
Douglas Gregor336fd812010-01-23 00:40:08 +00001587 return VisitCastExpr(E);
1588}
1589
Douglas Gregor36897b02010-09-10 00:22:18 +00001590bool CursorVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1591 return Visit(MakeCursorLabelRef(E->getLabel(), E->getLabelLoc(), TU));
1592}
1593
Douglas Gregor648220e2010-08-10 15:02:34 +00001594bool CursorVisitor::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
1595 return Visit(E->getArgTInfo1()->getTypeLoc()) ||
1596 Visit(E->getArgTInfo2()->getTypeLoc());
1597}
1598
1599bool CursorVisitor::VisitVAArgExpr(VAArgExpr *E) {
1600 if (Visit(E->getWrittenTypeInfo()->getTypeLoc()))
1601 return true;
1602
1603 return Visit(MakeCXCursor(E->getSubExpr(), StmtParent, TU));
1604}
1605
Douglas Gregorfa2e26f2010-09-09 23:28:23 +00001606bool CursorVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1607 // Visit the designators.
1608 typedef DesignatedInitExpr::Designator Designator;
1609 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
1610 DEnd = E->designators_end();
1611 D != DEnd; ++D) {
1612 if (D->isFieldDesignator()) {
1613 if (FieldDecl *Field = D->getField())
1614 if (Visit(MakeCursorMemberRef(Field, D->getFieldLoc(), TU)))
1615 return true;
1616
1617 continue;
1618 }
1619
1620 if (D->isArrayDesignator()) {
1621 if (Visit(MakeCXCursor(E->getArrayIndex(*D), StmtParent, TU)))
1622 return true;
1623
1624 continue;
1625 }
1626
1627 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1628 if (Visit(MakeCXCursor(E->getArrayRangeStart(*D), StmtParent, TU)) ||
1629 Visit(MakeCXCursor(E->getArrayRangeEnd(*D), StmtParent, TU)))
1630 return true;
1631 }
1632
1633 // Visit the initializer value itself.
1634 return Visit(MakeCXCursor(E->getInit(), StmtParent, TU));
1635}
1636
Douglas Gregor94802292010-09-02 21:20:16 +00001637bool CursorVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1638 if (E->isTypeOperand()) {
1639 if (TypeSourceInfo *TSInfo = E->getTypeOperandSourceInfo())
1640 return Visit(TSInfo->getTypeLoc());
1641
1642 return false;
1643 }
1644
1645 return VisitExpr(E);
1646}
1647
Douglas Gregor3d37c0a2010-09-09 16:14:44 +00001648bool CursorVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1649 if (E->isTypeOperand()) {
1650 if (TypeSourceInfo *TSInfo = E->getTypeOperandSourceInfo())
1651 return Visit(TSInfo->getTypeLoc());
1652
1653 return false;
1654 }
1655
1656 return VisitExpr(E);
1657}
1658
Douglas Gregorab6677e2010-09-08 00:15:04 +00001659bool CursorVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1660 if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo())
Douglas Gregor40749ee2010-11-03 00:35:38 +00001661 if (Visit(TSInfo->getTypeLoc()))
1662 return true;
Douglas Gregorab6677e2010-09-08 00:15:04 +00001663
1664 return VisitExpr(E);
1665}
1666
1667bool CursorVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1668 if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo())
1669 return Visit(TSInfo->getTypeLoc());
1670
1671 return false;
1672}
1673
Douglas Gregor1bb2a932010-09-07 21:49:58 +00001674bool CursorVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1675 // Visit placement arguments.
1676 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I)
1677 if (Visit(MakeCXCursor(E->getPlacementArg(I), StmtParent, TU)))
1678 return true;
1679
1680 // Visit the allocated type.
1681 if (TypeSourceInfo *TSInfo = E->getAllocatedTypeSourceInfo())
1682 if (Visit(TSInfo->getTypeLoc()))
1683 return true;
1684
1685 // Visit the array size, if any.
1686 if (E->isArray() && Visit(MakeCXCursor(E->getArraySize(), StmtParent, TU)))
1687 return true;
1688
1689 // Visit the initializer or constructor arguments.
1690 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I)
1691 if (Visit(MakeCXCursor(E->getConstructorArg(I), StmtParent, TU)))
1692 return true;
1693
1694 return false;
1695}
1696
Douglas Gregor6f7198f2010-09-02 22:09:03 +00001697bool CursorVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1698 // Visit base expression.
1699 if (Visit(MakeCXCursor(E->getBase(), StmtParent, TU)))
1700 return true;
1701
1702 // Visit the nested-name-specifier.
1703 if (NestedNameSpecifier *Qualifier = E->getQualifier())
1704 if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange()))
1705 return true;
1706
1707 // Visit the scope type that looks disturbingly like the nested-name-specifier
1708 // but isn't.
1709 if (TypeSourceInfo *TSInfo = E->getScopeTypeInfo())
1710 if (Visit(TSInfo->getTypeLoc()))
1711 return true;
1712
1713 // Visit the name of the type being destroyed.
1714 if (TypeSourceInfo *TSInfo = E->getDestroyedTypeInfo())
1715 if (Visit(TSInfo->getTypeLoc()))
1716 return true;
1717
1718 return false;
1719}
1720
Douglas Gregor3d37c0a2010-09-09 16:14:44 +00001721bool CursorVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1722 return Visit(E->getQueriedTypeSourceInfo()->getTypeLoc());
1723}
1724
Douglas Gregor1f7b5902010-09-02 22:29:21 +00001725bool CursorVisitor::VisitOverloadExpr(OverloadExpr *E) {
Douglas Gregor8ab670e2010-09-02 22:19:24 +00001726 // Visit the nested-name-specifier.
1727 if (NestedNameSpecifier *Qualifier = E->getQualifier())
1728 if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange()))
1729 return true;
1730
1731 // Visit the declaration name.
1732 if (VisitDeclarationNameInfo(E->getNameInfo()))
1733 return true;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001734
1735 // Visit the overloaded declaration reference.
1736 if (Visit(MakeCursorOverloadedDeclRef(E, TU)))
1737 return true;
1738
Douglas Gregor1f7b5902010-09-02 22:29:21 +00001739 // Visit the explicitly-specified template arguments.
1740 if (const ExplicitTemplateArgumentList *ArgList
1741 = E->getOptionalExplicitTemplateArgs()) {
1742 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
1743 *ArgEnd = Arg + ArgList->NumTemplateArgs;
1744 Arg != ArgEnd; ++Arg) {
1745 if (VisitTemplateArgumentLoc(*Arg))
1746 return true;
1747 }
1748 }
1749
Douglas Gregor8ab670e2010-09-02 22:19:24 +00001750 return false;
1751}
1752
Douglas Gregorbfebed22010-09-03 17:24:10 +00001753bool CursorVisitor::VisitDependentScopeDeclRefExpr(
1754 DependentScopeDeclRefExpr *E) {
1755 // Visit the nested-name-specifier.
1756 if (NestedNameSpecifier *Qualifier = E->getQualifier())
1757 if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange()))
1758 return true;
1759
1760 // Visit the declaration name.
1761 if (VisitDeclarationNameInfo(E->getNameInfo()))
1762 return true;
1763
1764 // Visit the explicitly-specified template arguments.
1765 if (const ExplicitTemplateArgumentList *ArgList
1766 = E->getOptionalExplicitTemplateArgs()) {
1767 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
1768 *ArgEnd = Arg + ArgList->NumTemplateArgs;
1769 Arg != ArgEnd; ++Arg) {
1770 if (VisitTemplateArgumentLoc(*Arg))
1771 return true;
1772 }
1773 }
1774
1775 return false;
1776}
1777
Douglas Gregorab6677e2010-09-08 00:15:04 +00001778bool CursorVisitor::VisitCXXUnresolvedConstructExpr(
1779 CXXUnresolvedConstructExpr *E) {
1780 if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo())
1781 if (Visit(TSInfo->getTypeLoc()))
1782 return true;
1783
1784 return VisitExpr(E);
1785}
1786
Douglas Gregor25d63622010-09-03 17:35:34 +00001787bool CursorVisitor::VisitCXXDependentScopeMemberExpr(
1788 CXXDependentScopeMemberExpr *E) {
1789 // Visit the base expression, if there is one.
1790 if (!E->isImplicitAccess() &&
1791 Visit(MakeCXCursor(E->getBase(), StmtParent, TU)))
1792 return true;
1793
1794 // Visit the nested-name-specifier.
1795 if (NestedNameSpecifier *Qualifier = E->getQualifier())
1796 if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange()))
1797 return true;
1798
1799 // Visit the declaration name.
1800 if (VisitDeclarationNameInfo(E->getMemberNameInfo()))
1801 return true;
1802
1803 // Visit the explicitly-specified template arguments.
1804 if (const ExplicitTemplateArgumentList *ArgList
1805 = E->getOptionalExplicitTemplateArgs()) {
1806 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
1807 *ArgEnd = Arg + ArgList->NumTemplateArgs;
1808 Arg != ArgEnd; ++Arg) {
1809 if (VisitTemplateArgumentLoc(*Arg))
1810 return true;
1811 }
1812 }
1813
1814 return false;
1815}
1816
Douglas Gregoraaa80b22010-09-03 18:01:25 +00001817bool CursorVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
1818 // Visit the base expression, if there is one.
1819 if (!E->isImplicitAccess() &&
1820 Visit(MakeCXCursor(E->getBase(), StmtParent, TU)))
1821 return true;
1822
1823 return VisitOverloadExpr(E);
1824}
Douglas Gregor25d63622010-09-03 17:35:34 +00001825
Douglas Gregorc2350e52010-03-08 16:40:19 +00001826bool CursorVisitor::VisitObjCMessageExpr(ObjCMessageExpr *E) {
Douglas Gregor04badcf2010-04-21 00:45:42 +00001827 if (TypeSourceInfo *TSInfo = E->getClassReceiverTypeInfo())
1828 if (Visit(TSInfo->getTypeLoc()))
1829 return true;
Douglas Gregorc2350e52010-03-08 16:40:19 +00001830
1831 return VisitExpr(E);
1832}
1833
Douglas Gregor81d34662010-04-20 15:39:42 +00001834bool CursorVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
1835 return Visit(E->getEncodedTypeSourceInfo()->getTypeLoc());
1836}
1837
1838
Ted Kremenek09dfa372010-02-18 05:46:33 +00001839bool CursorVisitor::VisitAttributes(Decl *D) {
Sean Huntcf807c42010-08-18 23:23:40 +00001840 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1841 i != e; ++i)
1842 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek09dfa372010-02-18 05:46:33 +00001843 return true;
1844
1845 return false;
1846}
1847
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001848//===----------------------------------------------------------------------===//
1849// Data-recursive visitor methods.
1850//===----------------------------------------------------------------------===//
1851
Ted Kremeneka6b70432010-11-12 21:34:09 +00001852static void EnqueueChildren(VisitorWorkList &WL, CXCursor Parent, Stmt *S) {
1853 unsigned size = WL.size();
1854 for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end();
1855 Child != ChildEnd; ++Child) {
1856 WLAddStmt(WL, Parent, *Child);
1857 }
1858 if (size == WL.size())
1859 return;
1860 // Now reverse the entries we just added. This will match the DFS
1861 // ordering performed by the worklist.
1862 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1863 std::reverse(I, E);
1864}
1865
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001866void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
1867 CXCursor C = MakeCXCursor(S, StmtParent, TU);
1868 switch (S->getStmtClass()) {
Ted Kremeneka6b70432010-11-12 21:34:09 +00001869 default:
1870 EnqueueChildren(WL, C, S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001871 break;
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00001872 case Stmt::CompoundLiteralExprClass: {
1873 CompoundLiteralExpr *CL = cast<CompoundLiteralExpr>(S);
1874 EnqueueChildren(WL, C, CL);
1875 WLAddTypeLoc(WL, C, CL->getTypeSourceInfo());
1876 break;
1877 }
Ted Kremenekf1107452010-11-12 18:26:56 +00001878 case Stmt::CXXOperatorCallExprClass: {
1879 CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(S);
1880 // Note that we enqueue things in reverse order so that
1881 // they are visited correctly by the DFS.
Ted Kremenekf1107452010-11-12 18:26:56 +00001882 for (unsigned I = 1, N = CE->getNumArgs(); I != N; ++I)
Ted Kremenekae3c2202010-11-12 18:27:01 +00001883 WLAddStmt(WL, C, CE->getArg(N-I));
Ted Kremenekf1107452010-11-12 18:26:56 +00001884
Ted Kremenekae3c2202010-11-12 18:27:01 +00001885 WLAddStmt(WL, C, CE->getCallee());
1886 WLAddStmt(WL, C, CE->getArg(0));
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001887 break;
1888 }
1889 case Stmt::BinaryOperatorClass: {
1890 BinaryOperator *B = cast<BinaryOperator>(S);
Ted Kremenekae3c2202010-11-12 18:27:01 +00001891 WLAddStmt(WL, C, B->getRHS());
1892 WLAddStmt(WL, C, B->getLHS());
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001893 break;
1894 }
Ted Kremenekbb677132010-11-12 18:27:04 +00001895 case Stmt::ForStmtClass: {
1896 ForStmt *FS = cast<ForStmt>(S);
1897 WLAddStmt(WL, C, FS->getBody());
1898 WLAddStmt(WL, C, FS->getInc());
1899 WLAddStmt(WL, C, FS->getCond());
1900 WLAddDecl(WL, C, FS->getConditionVariable());
1901 WLAddStmt(WL, C, FS->getInit());
1902 break;
1903 }
Ted Kremenekc70ebba2010-11-12 18:26:58 +00001904 case Stmt::IfStmtClass: {
1905 IfStmt *If = cast<IfStmt>(S);
1906 WLAddStmt(WL, C, If->getElse());
1907 WLAddStmt(WL, C, If->getThen());
1908 WLAddStmt(WL, C, If->getCond());
Ted Kremenekae3c2202010-11-12 18:27:01 +00001909 WLAddDecl(WL, C, If->getConditionVariable());
Ted Kremenekc70ebba2010-11-12 18:26:58 +00001910 break;
1911 }
Ted Kremeneka6b70432010-11-12 21:34:09 +00001912 case Stmt::InitListExprClass: {
1913 InitListExpr *IE = cast<InitListExpr>(S);
1914 // We care about the syntactic form of the initializer list, only.
1915 if (InitListExpr *Syntactic = IE->getSyntacticForm())
1916 IE = Syntactic;
1917 EnqueueChildren(WL, C, IE);
1918 break;
1919 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001920 case Stmt::MemberExprClass: {
1921 MemberExpr *M = cast<MemberExpr>(S);
1922 WL.push_back(MemberExprParts(M, C));
Ted Kremenekae3c2202010-11-12 18:27:01 +00001923 WLAddStmt(WL, C, M->getBase());
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001924 break;
1925 }
Ted Kremenekf1107452010-11-12 18:26:56 +00001926 case Stmt::ParenExprClass: {
Ted Kremenekae3c2202010-11-12 18:27:01 +00001927 WLAddStmt(WL, C, cast<ParenExpr>(S)->getSubExpr());
Ted Kremenekf1107452010-11-12 18:26:56 +00001928 break;
1929 }
1930 case Stmt::SwitchStmtClass: {
1931 SwitchStmt *SS = cast<SwitchStmt>(S);
Ted Kremenekae3c2202010-11-12 18:27:01 +00001932 WLAddStmt(WL, C, SS->getBody());
1933 WLAddStmt(WL, C, SS->getCond());
1934 WLAddDecl(WL, C, SS->getConditionVariable());
Ted Kremenek8c269ac2010-11-11 23:11:43 +00001935 break;
1936 }
Ted Kremenekbb677132010-11-12 18:27:04 +00001937 case Stmt::WhileStmtClass: {
1938 WhileStmt *W = cast<WhileStmt>(S);
1939 WLAddStmt(WL, C, W->getBody());
1940 WLAddStmt(WL, C, W->getCond());
1941 WLAddDecl(WL, C, W->getConditionVariable());
1942 break;
1943 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001944 }
1945}
1946
1947bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
1948 if (RegionOfInterest.isValid()) {
1949 SourceRange Range = getRawCursorExtent(C);
1950 if (Range.isInvalid() || CompareRegionOfInterest(Range))
1951 return false;
1952 }
1953 return true;
1954}
1955
1956bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
1957 while (!WL.empty()) {
1958 // Dequeue the worklist item.
1959 VisitorJob LI = WL.back(); WL.pop_back();
1960
1961 // Set the Parent field, then back to its old value once we're done.
1962 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
1963
1964 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00001965 case VisitorJob::DeclVisitKind: {
1966 Decl *D = cast<DeclVisit>(LI).get();
1967 if (!D)
1968 continue;
1969
1970 // For now, perform default visitation for Decls.
1971 if (Visit(MakeCXCursor(D, TU)))
1972 return true;
1973
1974 continue;
1975 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00001976 case VisitorJob::TypeLocVisitKind: {
1977 // Perform default visitation for TypeLocs.
1978 if (Visit(cast<TypeLocVisit>(LI).get()))
1979 return true;
1980 continue;
1981 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001982 case VisitorJob::StmtVisitKind: {
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001983 Stmt *S = cast<StmtVisit>(LI).get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00001984 if (!S)
1985 continue;
1986
Ted Kremenekf1107452010-11-12 18:26:56 +00001987 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001988 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
1989
1990 switch (S->getStmtClass()) {
1991 default: {
1992 // Perform default visitation for other cases.
1993 if (Visit(Cursor))
1994 return true;
1995 continue;
1996 }
Ted Kremenekf1107452010-11-12 18:26:56 +00001997 case Stmt::BinaryOperatorClass:
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001998 case Stmt::CallExprClass:
Ted Kremenekf1107452010-11-12 18:26:56 +00001999 case Stmt::CaseStmtClass:
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002000 case Stmt::CompoundLiteralExprClass:
Ted Kremenekf1107452010-11-12 18:26:56 +00002001 case Stmt::CompoundStmtClass:
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002002 case Stmt::CXXMemberCallExprClass:
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002003 case Stmt::CXXOperatorCallExprClass:
Ted Kremenekf1107452010-11-12 18:26:56 +00002004 case Stmt::DefaultStmtClass:
Ted Kremenekbb677132010-11-12 18:27:04 +00002005 case Stmt::DoStmtClass:
2006 case Stmt::ForStmtClass:
Ted Kremenekc70ebba2010-11-12 18:26:58 +00002007 case Stmt::IfStmtClass:
Ted Kremeneka6b70432010-11-12 21:34:09 +00002008 case Stmt::InitListExprClass:
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002009 case Stmt::MemberExprClass:
Ted Kremenekf1107452010-11-12 18:26:56 +00002010 case Stmt::ParenExprClass:
2011 case Stmt::SwitchStmtClass:
Ted Kremenekae3c2202010-11-12 18:27:01 +00002012 case Stmt::UnaryOperatorClass:
Ted Kremenekbb677132010-11-12 18:27:04 +00002013 case Stmt::WhileStmtClass:
Ted Kremenekf1107452010-11-12 18:26:56 +00002014 {
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002015 if (!IsInRegionOfInterest(Cursor))
2016 continue;
2017 switch (Visitor(Cursor, Parent, ClientData)) {
2018 case CXChildVisit_Break:
2019 return true;
2020 case CXChildVisit_Continue:
2021 break;
2022 case CXChildVisit_Recurse:
2023 EnqueueWorkList(WL, S);
2024 break;
2025 }
2026 }
2027 }
2028 continue;
2029 }
2030 case VisitorJob::MemberExprPartsKind: {
2031 // Handle the other pieces in the MemberExpr besides the base.
2032 MemberExpr *M = cast<MemberExprParts>(LI).get();
2033
2034 // Visit the nested-name-specifier
2035 if (NestedNameSpecifier *Qualifier = M->getQualifier())
2036 if (VisitNestedNameSpecifier(Qualifier, M->getQualifierRange()))
2037 return true;
2038
2039 // Visit the declaration name.
2040 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2041 return true;
2042
2043 // Visit the explicitly-specified template arguments, if any.
2044 if (M->hasExplicitTemplateArgs()) {
2045 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2046 *ArgEnd = Arg + M->getNumTemplateArgs();
2047 Arg != ArgEnd; ++Arg) {
2048 if (VisitTemplateArgumentLoc(*Arg))
2049 return true;
2050 }
2051 }
2052 continue;
2053 }
2054 }
2055 }
2056 return false;
2057}
2058
2059bool CursorVisitor::VisitDataRecursive(Stmt *S) {
2060 VisitorWorkList WL;
2061 EnqueueWorkList(WL, S);
2062 return RunVisitorWorkList(WL);
2063}
2064
2065//===----------------------------------------------------------------------===//
2066// Misc. API hooks.
2067//===----------------------------------------------------------------------===//
2068
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002069static llvm::sys::Mutex EnableMultithreadingMutex;
2070static bool EnabledMultithreading;
2071
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002072extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002073CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2074 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002075 // Disable pretty stack trace functionality, which will otherwise be a very
2076 // poor citizen of the world and set up all sorts of signal handlers.
2077 llvm::DisablePrettyStackTrace = true;
2078
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002079 // We use crash recovery to make some of our APIs more reliable, implicitly
2080 // enable it.
2081 llvm::CrashRecoveryContext::Enable();
2082
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002083 // Enable support for multithreading in LLVM.
2084 {
2085 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2086 if (!EnabledMultithreading) {
2087 llvm::llvm_start_multithreaded();
2088 EnabledMultithreading = true;
2089 }
2090 }
2091
Douglas Gregora030b7c2010-01-22 20:35:53 +00002092 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002093 if (excludeDeclarationsFromPCH)
2094 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002095 if (displayDiagnostics)
2096 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002097 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002098}
2099
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002100void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002101 if (CIdx)
2102 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002103}
2104
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002105CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002106 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002107 if (!CIdx)
2108 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002109
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002110 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002111 FileSystemOptions FileSystemOpts;
2112 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002113
Douglas Gregor28019772010-04-05 23:52:57 +00002114 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002115 return ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002116 CXXIdx->getOnlyLocalDecls(),
2117 0, 0, true);
Steve Naroff600866c2009-08-27 19:51:58 +00002118}
2119
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002120unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002121 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002122 CXTranslationUnit_CacheCompletionResults |
2123 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002124}
2125
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002126CXTranslationUnit
2127clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2128 const char *source_filename,
2129 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002130 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002131 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002132 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor5a430212010-07-21 18:52:53 +00002133 return clang_parseTranslationUnit(CIdx, source_filename,
2134 command_line_args, num_command_line_args,
2135 unsaved_files, num_unsaved_files,
2136 CXTranslationUnit_DetailedPreprocessingRecord);
2137}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002138
2139struct ParseTranslationUnitInfo {
2140 CXIndex CIdx;
2141 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002142 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002143 int num_command_line_args;
2144 struct CXUnsavedFile *unsaved_files;
2145 unsigned num_unsaved_files;
2146 unsigned options;
2147 CXTranslationUnit result;
2148};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002149static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002150 ParseTranslationUnitInfo *PTUI =
2151 static_cast<ParseTranslationUnitInfo*>(UserData);
2152 CXIndex CIdx = PTUI->CIdx;
2153 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002154 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002155 int num_command_line_args = PTUI->num_command_line_args;
2156 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2157 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2158 unsigned options = PTUI->options;
2159 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002160
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002161 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002162 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002163
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002164 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2165
Douglas Gregor44c181a2010-07-23 00:33:23 +00002166 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002167 bool CompleteTranslationUnit
2168 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002169 bool CacheCodeCompetionResults
2170 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002171 bool CXXPrecompilePreamble
2172 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2173 bool CXXChainedPCH
2174 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002175
Douglas Gregor5352ac02010-01-28 00:27:43 +00002176 // Configure the diagnostics.
2177 DiagnosticOptions DiagOpts;
Douglas Gregor28019772010-04-05 23:52:57 +00002178 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
2179 Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002180
Douglas Gregor4db64a42010-01-23 00:14:00 +00002181 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2182 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002183 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002184 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002185 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregor4db64a42010-01-23 00:14:00 +00002186 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2187 Buffer));
2188 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002189
Douglas Gregorb10daed2010-10-11 16:52:23 +00002190 llvm::SmallVector<const char *, 16> Args;
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002191
Ted Kremenek139ba862009-10-22 00:03:57 +00002192 // The 'source_filename' argument is optional. If the caller does not
2193 // specify it then it is assumed that the source file is specified
2194 // in the actual argument list.
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002195 if (source_filename)
Douglas Gregorb10daed2010-10-11 16:52:23 +00002196 Args.push_back(source_filename);
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002197
2198 // Since the Clang C library is primarily used by batch tools dealing with
2199 // (often very broken) source code, where spell-checking can have a
2200 // significant negative impact on performance (particularly when
2201 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002202 // Only do this if we haven't found a spell-checking-related argument.
2203 bool FoundSpellCheckingArgument = false;
2204 for (int I = 0; I != num_command_line_args; ++I) {
2205 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2206 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2207 FoundSpellCheckingArgument = true;
2208 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002209 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002210 }
2211 if (!FoundSpellCheckingArgument)
2212 Args.push_back("-fno-spell-checking");
2213
2214 Args.insert(Args.end(), command_line_args,
2215 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002216
Douglas Gregor44c181a2010-07-23 00:33:23 +00002217 // Do we need the detailed preprocessing record?
2218 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002219 Args.push_back("-Xclang");
2220 Args.push_back("-detailed-preprocessing-record");
Douglas Gregor44c181a2010-07-23 00:33:23 +00002221 }
2222
Douglas Gregorb10daed2010-10-11 16:52:23 +00002223 unsigned NumErrors = Diags->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002224 llvm::OwningPtr<ASTUnit> Unit(
2225 ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
2226 Diags,
2227 CXXIdx->getClangResourcesPath(),
2228 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002229 /*CaptureDiagnostics=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002230 RemappedFiles.data(),
2231 RemappedFiles.size(),
Douglas Gregorb10daed2010-10-11 16:52:23 +00002232 PrecompilePreamble,
2233 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002234 CacheCodeCompetionResults,
2235 CXXPrecompilePreamble,
2236 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002237
Douglas Gregorb10daed2010-10-11 16:52:23 +00002238 if (NumErrors != Diags->getNumErrors()) {
2239 // Make sure to check that 'Unit' is non-NULL.
2240 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2241 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2242 DEnd = Unit->stored_diag_end();
2243 D != DEnd; ++D) {
2244 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2245 CXString Msg = clang_formatDiagnostic(&Diag,
2246 clang_defaultDiagnosticDisplayOptions());
2247 fprintf(stderr, "%s\n", clang_getCString(Msg));
2248 clang_disposeString(Msg);
2249 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002250#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002251 // On Windows, force a flush, since there may be multiple copies of
2252 // stderr and stdout in the file system, all with different buffers
2253 // but writing to the same device.
2254 fflush(stderr);
2255#endif
2256 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002257 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002258
Douglas Gregorb10daed2010-10-11 16:52:23 +00002259 PTUI->result = Unit.take();
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002260}
2261CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2262 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002263 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002264 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002265 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002266 unsigned num_unsaved_files,
2267 unsigned options) {
2268 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002269 num_command_line_args, unsaved_files,
2270 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002271 llvm::CrashRecoveryContext CRC;
2272
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002273 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002274 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2275 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2276 fprintf(stderr, " 'command_line_args' : [");
2277 for (int i = 0; i != num_command_line_args; ++i) {
2278 if (i)
2279 fprintf(stderr, ", ");
2280 fprintf(stderr, "'%s'", command_line_args[i]);
2281 }
2282 fprintf(stderr, "],\n");
2283 fprintf(stderr, " 'unsaved_files' : [");
2284 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2285 if (i)
2286 fprintf(stderr, ", ");
2287 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2288 unsaved_files[i].Length);
2289 }
2290 fprintf(stderr, "],\n");
2291 fprintf(stderr, " 'options' : %d,\n", options);
2292 fprintf(stderr, "}\n");
2293
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002294 return 0;
2295 }
2296
2297 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002298}
2299
Douglas Gregor19998442010-08-13 15:35:05 +00002300unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2301 return CXSaveTranslationUnit_None;
2302}
2303
2304int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2305 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002306 if (!TU)
2307 return 1;
2308
2309 return static_cast<ASTUnit *>(TU)->Save(FileName);
2310}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002311
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002312void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002313 if (CTUnit) {
2314 // If the translation unit has been marked as unsafe to free, just discard
2315 // it.
2316 if (static_cast<ASTUnit *>(CTUnit)->isUnsafeToFree())
2317 return;
2318
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002319 delete static_cast<ASTUnit *>(CTUnit);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002320 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002321}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002322
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002323unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2324 return CXReparse_None;
2325}
2326
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002327struct ReparseTranslationUnitInfo {
2328 CXTranslationUnit TU;
2329 unsigned num_unsaved_files;
2330 struct CXUnsavedFile *unsaved_files;
2331 unsigned options;
2332 int result;
2333};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002334
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002335static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002336 ReparseTranslationUnitInfo *RTUI =
2337 static_cast<ReparseTranslationUnitInfo*>(UserData);
2338 CXTranslationUnit TU = RTUI->TU;
2339 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2340 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2341 unsigned options = RTUI->options;
2342 (void) options;
2343 RTUI->result = 1;
2344
Douglas Gregorabc563f2010-07-19 21:46:24 +00002345 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002346 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002347
2348 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
2349 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002350
2351 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2352 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2353 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2354 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002355 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002356 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2357 Buffer));
2358 }
2359
Douglas Gregor593b0c12010-09-23 18:47:53 +00002360 if (!CXXUnit->Reparse(RemappedFiles.data(), RemappedFiles.size()))
2361 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002362}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002363
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002364int clang_reparseTranslationUnit(CXTranslationUnit TU,
2365 unsigned num_unsaved_files,
2366 struct CXUnsavedFile *unsaved_files,
2367 unsigned options) {
2368 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2369 options, 0 };
2370 llvm::CrashRecoveryContext CRC;
2371
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002372 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002373 fprintf(stderr, "libclang: crash detected during reparsing\n");
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002374 static_cast<ASTUnit *>(TU)->setUnsafeToFree(true);
2375 return 1;
2376 }
2377
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002378
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002379 return RTUI.result;
2380}
2381
Douglas Gregordf95a132010-08-09 20:45:32 +00002382
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002383CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002384 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002385 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002386
Steve Naroff77accc12009-09-03 18:19:54 +00002387 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002388 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002389}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002390
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002391CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002392 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002393 return Result;
2394}
2395
Ted Kremenekfb480492010-01-13 21:46:36 +00002396} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002397
Ted Kremenekfb480492010-01-13 21:46:36 +00002398//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002399// CXSourceLocation and CXSourceRange Operations.
2400//===----------------------------------------------------------------------===//
2401
Douglas Gregorb9790342010-01-22 21:44:22 +00002402extern "C" {
2403CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002404 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002405 return Result;
2406}
2407
2408unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002409 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2410 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2411 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002412}
2413
2414CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2415 CXFile file,
2416 unsigned line,
2417 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002418 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002419 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002420
Douglas Gregorb9790342010-01-22 21:44:22 +00002421 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu);
2422 SourceLocation SLoc
2423 = CXXUnit->getSourceManager().getLocation(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002424 static_cast<const FileEntry *>(file),
Douglas Gregorb9790342010-01-22 21:44:22 +00002425 line, column);
David Chisnall83889a72010-10-15 17:07:39 +00002426 if (SLoc.isInvalid()) return clang_getNullLocation();
2427
2428 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2429}
2430
2431CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2432 CXFile file,
2433 unsigned offset) {
2434 if (!tu || !file)
2435 return clang_getNullLocation();
2436
2437 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu);
2438 SourceLocation Start
2439 = CXXUnit->getSourceManager().getLocation(
2440 static_cast<const FileEntry *>(file),
2441 1, 1);
2442 if (Start.isInvalid()) return clang_getNullLocation();
2443
2444 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2445
2446 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002447
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002448 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002449}
2450
Douglas Gregor5352ac02010-01-28 00:27:43 +00002451CXSourceRange clang_getNullRange() {
2452 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2453 return Result;
2454}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002455
Douglas Gregor5352ac02010-01-28 00:27:43 +00002456CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2457 if (begin.ptr_data[0] != end.ptr_data[0] ||
2458 begin.ptr_data[1] != end.ptr_data[1])
2459 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002460
2461 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002462 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002463 return Result;
2464}
2465
Douglas Gregor46766dc2010-01-26 19:19:08 +00002466void clang_getInstantiationLocation(CXSourceLocation location,
2467 CXFile *file,
2468 unsigned *line,
2469 unsigned *column,
2470 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002471 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2472
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002473 if (!location.ptr_data[0] || Loc.isInvalid()) {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002474 if (file)
2475 *file = 0;
2476 if (line)
2477 *line = 0;
2478 if (column)
2479 *column = 0;
2480 if (offset)
2481 *offset = 0;
2482 return;
2483 }
2484
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002485 const SourceManager &SM =
2486 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002487 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002488
2489 if (file)
2490 *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));
2491 if (line)
2492 *line = SM.getInstantiationLineNumber(InstLoc);
2493 if (column)
2494 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002495 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002496 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002497}
2498
Douglas Gregora9b06d42010-11-09 06:24:54 +00002499void clang_getSpellingLocation(CXSourceLocation location,
2500 CXFile *file,
2501 unsigned *line,
2502 unsigned *column,
2503 unsigned *offset) {
2504 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2505
2506 if (!location.ptr_data[0] || Loc.isInvalid()) {
2507 if (file)
2508 *file = 0;
2509 if (line)
2510 *line = 0;
2511 if (column)
2512 *column = 0;
2513 if (offset)
2514 *offset = 0;
2515 return;
2516 }
2517
2518 const SourceManager &SM =
2519 *static_cast<const SourceManager*>(location.ptr_data[0]);
2520 SourceLocation SpellLoc = Loc;
2521 if (SpellLoc.isMacroID()) {
2522 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2523 if (SimpleSpellingLoc.isFileID() &&
2524 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2525 SpellLoc = SimpleSpellingLoc;
2526 else
2527 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2528 }
2529
2530 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2531 FileID FID = LocInfo.first;
2532 unsigned FileOffset = LocInfo.second;
2533
2534 if (file)
2535 *file = (void *)SM.getFileEntryForID(FID);
2536 if (line)
2537 *line = SM.getLineNumber(FID, FileOffset);
2538 if (column)
2539 *column = SM.getColumnNumber(FID, FileOffset);
2540 if (offset)
2541 *offset = FileOffset;
2542}
2543
Douglas Gregor1db19de2010-01-19 21:36:55 +00002544CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002545 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002546 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002547 return Result;
2548}
2549
2550CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002551 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002552 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002553 return Result;
2554}
2555
Douglas Gregorb9790342010-01-22 21:44:22 +00002556} // end: extern "C"
2557
Douglas Gregor1db19de2010-01-19 21:36:55 +00002558//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002559// CXFile Operations.
2560//===----------------------------------------------------------------------===//
2561
2562extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002563CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002564 if (!SFile)
Ted Kremenek74844072010-02-17 00:41:20 +00002565 return createCXString(NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002566
Steve Naroff88145032009-10-27 14:35:18 +00002567 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002568 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002569}
2570
2571time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002572 if (!SFile)
2573 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002574
Steve Naroff88145032009-10-27 14:35:18 +00002575 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2576 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002577}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002578
Douglas Gregorb9790342010-01-22 21:44:22 +00002579CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2580 if (!tu)
2581 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002582
Douglas Gregorb9790342010-01-22 21:44:22 +00002583 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002584
Douglas Gregorb9790342010-01-22 21:44:22 +00002585 FileManager &FMgr = CXXUnit->getFileManager();
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002586 const FileEntry *File = FMgr.getFile(file_name, file_name+strlen(file_name),
2587 CXXUnit->getFileSystemOpts());
Douglas Gregorb9790342010-01-22 21:44:22 +00002588 return const_cast<FileEntry *>(File);
2589}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002590
Ted Kremenekfb480492010-01-13 21:46:36 +00002591} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002592
Ted Kremenekfb480492010-01-13 21:46:36 +00002593//===----------------------------------------------------------------------===//
2594// CXCursor Operations.
2595//===----------------------------------------------------------------------===//
2596
Ted Kremenekfb480492010-01-13 21:46:36 +00002597static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002598 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2599 return getDeclFromExpr(CE->getSubExpr());
2600
Ted Kremenekfb480492010-01-13 21:46:36 +00002601 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2602 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002603 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2604 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002605 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2606 return ME->getMemberDecl();
2607 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2608 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002609 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
2610 return PRE->getProperty();
2611
Ted Kremenekfb480492010-01-13 21:46:36 +00002612 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2613 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002614 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2615 if (!CE->isElidable())
2616 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002617 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2618 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002619
Douglas Gregordb1314e2010-10-01 21:11:22 +00002620 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2621 return PE->getProtocol();
2622
Ted Kremenekfb480492010-01-13 21:46:36 +00002623 return 0;
2624}
2625
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002626static SourceLocation getLocationFromExpr(Expr *E) {
2627 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2628 return /*FIXME:*/Msg->getLeftLoc();
2629 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2630 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002631 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2632 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002633 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2634 return Member->getMemberLoc();
2635 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2636 return Ivar->getLocation();
2637 return E->getLocStart();
2638}
2639
Ted Kremenekfb480492010-01-13 21:46:36 +00002640extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002641
2642unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002643 CXCursorVisitor visitor,
2644 CXClientData client_data) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002645 ASTUnit *CXXUnit = getCursorASTUnit(parent);
Douglas Gregorb1373d02010-01-20 20:59:29 +00002646
Douglas Gregoreb8837b2010-08-03 19:06:41 +00002647 CursorVisitor CursorVis(CXXUnit, visitor, client_data,
2648 CXXUnit->getMaxPCHLevel());
Douglas Gregorb1373d02010-01-20 20:59:29 +00002649 return CursorVis.VisitChildren(parent);
2650}
2651
David Chisnall3387c652010-11-03 14:12:26 +00002652#ifndef __has_feature
2653#define __has_feature(x) 0
2654#endif
2655#if __has_feature(blocks)
2656typedef enum CXChildVisitResult
2657 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2658
2659static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2660 CXClientData client_data) {
2661 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2662 return block(cursor, parent);
2663}
2664#else
2665// If we are compiled with a compiler that doesn't have native blocks support,
2666// define and call the block manually, so the
2667typedef struct _CXChildVisitResult
2668{
2669 void *isa;
2670 int flags;
2671 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002672 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2673 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002674} *CXCursorVisitorBlock;
2675
2676static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2677 CXClientData client_data) {
2678 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2679 return block->invoke(block, cursor, parent);
2680}
2681#endif
2682
2683
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002684unsigned clang_visitChildrenWithBlock(CXCursor parent,
2685 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002686 return clang_visitChildren(parent, visitWithBlock, block);
2687}
2688
Douglas Gregor78205d42010-01-20 21:45:58 +00002689static CXString getDeclSpelling(Decl *D) {
2690 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
2691 if (!ND)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002692 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002693
Douglas Gregor78205d42010-01-20 21:45:58 +00002694 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002695 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002696
Douglas Gregor78205d42010-01-20 21:45:58 +00002697 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2698 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2699 // and returns different names. NamedDecl returns the class name and
2700 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002701 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002702
Douglas Gregor0a35bce2010-09-01 03:07:18 +00002703 if (isa<UsingDirectiveDecl>(D))
2704 return createCXString("");
2705
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00002706 llvm::SmallString<1024> S;
2707 llvm::raw_svector_ostream os(S);
2708 ND->printName(os);
2709
2710 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00002711}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002712
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002713CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002714 if (clang_isTranslationUnit(C.kind))
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002715 return clang_getTranslationUnitSpelling(C.data[2]);
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002716
Steve Narofff334b4e2009-09-02 18:26:48 +00002717 if (clang_isReference(C.kind)) {
2718 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00002719 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00002720 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002721 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002722 }
2723 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00002724 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002725 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002726 }
2727 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00002728 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00002729 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002730 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002731 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00002732 case CXCursor_CXXBaseSpecifier: {
2733 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
2734 return createCXString(B->getType().getAsString());
2735 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002736 case CXCursor_TypeRef: {
2737 TypeDecl *Type = getCursorTypeRef(C).first;
2738 assert(Type && "Missing type decl");
2739
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002740 return createCXString(getCursorContext(C).getTypeDeclType(Type).
2741 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002742 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00002743 case CXCursor_TemplateRef: {
2744 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00002745 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00002746
2747 return createCXString(Template->getNameAsString());
2748 }
Douglas Gregor69319002010-08-31 23:48:11 +00002749
2750 case CXCursor_NamespaceRef: {
2751 NamedDecl *NS = getCursorNamespaceRef(C).first;
2752 assert(NS && "Missing namespace decl");
2753
2754 return createCXString(NS->getNameAsString());
2755 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002756
Douglas Gregora67e03f2010-09-09 21:42:20 +00002757 case CXCursor_MemberRef: {
2758 FieldDecl *Field = getCursorMemberRef(C).first;
2759 assert(Field && "Missing member decl");
2760
2761 return createCXString(Field->getNameAsString());
2762 }
2763
Douglas Gregor36897b02010-09-10 00:22:18 +00002764 case CXCursor_LabelRef: {
2765 LabelStmt *Label = getCursorLabelRef(C).first;
2766 assert(Label && "Missing label");
2767
2768 return createCXString(Label->getID()->getName());
2769 }
2770
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00002771 case CXCursor_OverloadedDeclRef: {
2772 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
2773 if (Decl *D = Storage.dyn_cast<Decl *>()) {
2774 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
2775 return createCXString(ND->getNameAsString());
2776 return createCXString("");
2777 }
2778 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
2779 return createCXString(E->getName().getAsString());
2780 OverloadedTemplateStorage *Ovl
2781 = Storage.get<OverloadedTemplateStorage*>();
2782 if (Ovl->size() == 0)
2783 return createCXString("");
2784 return createCXString((*Ovl->begin())->getNameAsString());
2785 }
2786
Daniel Dunbaracca7252009-11-30 20:42:49 +00002787 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002788 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00002789 }
2790 }
Douglas Gregor97b98722010-01-19 23:20:36 +00002791
2792 if (clang_isExpression(C.kind)) {
2793 Decl *D = getDeclFromExpr(getCursorExpr(C));
2794 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00002795 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002796 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00002797 }
2798
Douglas Gregor36897b02010-09-10 00:22:18 +00002799 if (clang_isStatement(C.kind)) {
2800 Stmt *S = getCursorStmt(C);
2801 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
2802 return createCXString(Label->getID()->getName());
2803
2804 return createCXString("");
2805 }
2806
Douglas Gregor4ae8f292010-03-18 17:52:52 +00002807 if (C.kind == CXCursor_MacroInstantiation)
2808 return createCXString(getCursorMacroInstantiation(C)->getName()
2809 ->getNameStart());
2810
Douglas Gregor572feb22010-03-18 18:04:21 +00002811 if (C.kind == CXCursor_MacroDefinition)
2812 return createCXString(getCursorMacroDefinition(C)->getName()
2813 ->getNameStart());
2814
Douglas Gregorecdcb882010-10-20 22:00:55 +00002815 if (C.kind == CXCursor_InclusionDirective)
2816 return createCXString(getCursorInclusionDirective(C)->getFileName());
2817
Douglas Gregor60cbfac2010-01-25 16:56:17 +00002818 if (clang_isDeclaration(C.kind))
2819 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00002820
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002821 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00002822}
2823
Douglas Gregor358559d2010-10-02 22:49:11 +00002824CXString clang_getCursorDisplayName(CXCursor C) {
2825 if (!clang_isDeclaration(C.kind))
2826 return clang_getCursorSpelling(C);
2827
2828 Decl *D = getCursorDecl(C);
2829 if (!D)
2830 return createCXString("");
2831
2832 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
2833 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
2834 D = FunTmpl->getTemplatedDecl();
2835
2836 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
2837 llvm::SmallString<64> Str;
2838 llvm::raw_svector_ostream OS(Str);
2839 OS << Function->getNameAsString();
2840 if (Function->getPrimaryTemplate())
2841 OS << "<>";
2842 OS << "(";
2843 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
2844 if (I)
2845 OS << ", ";
2846 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
2847 }
2848
2849 if (Function->isVariadic()) {
2850 if (Function->getNumParams())
2851 OS << ", ";
2852 OS << "...";
2853 }
2854 OS << ")";
2855 return createCXString(OS.str());
2856 }
2857
2858 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
2859 llvm::SmallString<64> Str;
2860 llvm::raw_svector_ostream OS(Str);
2861 OS << ClassTemplate->getNameAsString();
2862 OS << "<";
2863 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
2864 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
2865 if (I)
2866 OS << ", ";
2867
2868 NamedDecl *Param = Params->getParam(I);
2869 if (Param->getIdentifier()) {
2870 OS << Param->getIdentifier()->getName();
2871 continue;
2872 }
2873
2874 // There is no parameter name, which makes this tricky. Try to come up
2875 // with something useful that isn't too long.
2876 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
2877 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
2878 else if (NonTypeTemplateParmDecl *NTTP
2879 = dyn_cast<NonTypeTemplateParmDecl>(Param))
2880 OS << NTTP->getType().getAsString(Policy);
2881 else
2882 OS << "template<...> class";
2883 }
2884
2885 OS << ">";
2886 return createCXString(OS.str());
2887 }
2888
2889 if (ClassTemplateSpecializationDecl *ClassSpec
2890 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
2891 // If the type was explicitly written, use that.
2892 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
2893 return createCXString(TSInfo->getType().getAsString(Policy));
2894
2895 llvm::SmallString<64> Str;
2896 llvm::raw_svector_ostream OS(Str);
2897 OS << ClassSpec->getNameAsString();
2898 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00002899 ClassSpec->getTemplateArgs().data(),
2900 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00002901 Policy);
2902 return createCXString(OS.str());
2903 }
2904
2905 return clang_getCursorSpelling(C);
2906}
2907
Ted Kremeneke68fff62010-02-17 00:41:32 +00002908CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00002909 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00002910 case CXCursor_FunctionDecl:
2911 return createCXString("FunctionDecl");
2912 case CXCursor_TypedefDecl:
2913 return createCXString("TypedefDecl");
2914 case CXCursor_EnumDecl:
2915 return createCXString("EnumDecl");
2916 case CXCursor_EnumConstantDecl:
2917 return createCXString("EnumConstantDecl");
2918 case CXCursor_StructDecl:
2919 return createCXString("StructDecl");
2920 case CXCursor_UnionDecl:
2921 return createCXString("UnionDecl");
2922 case CXCursor_ClassDecl:
2923 return createCXString("ClassDecl");
2924 case CXCursor_FieldDecl:
2925 return createCXString("FieldDecl");
2926 case CXCursor_VarDecl:
2927 return createCXString("VarDecl");
2928 case CXCursor_ParmDecl:
2929 return createCXString("ParmDecl");
2930 case CXCursor_ObjCInterfaceDecl:
2931 return createCXString("ObjCInterfaceDecl");
2932 case CXCursor_ObjCCategoryDecl:
2933 return createCXString("ObjCCategoryDecl");
2934 case CXCursor_ObjCProtocolDecl:
2935 return createCXString("ObjCProtocolDecl");
2936 case CXCursor_ObjCPropertyDecl:
2937 return createCXString("ObjCPropertyDecl");
2938 case CXCursor_ObjCIvarDecl:
2939 return createCXString("ObjCIvarDecl");
2940 case CXCursor_ObjCInstanceMethodDecl:
2941 return createCXString("ObjCInstanceMethodDecl");
2942 case CXCursor_ObjCClassMethodDecl:
2943 return createCXString("ObjCClassMethodDecl");
2944 case CXCursor_ObjCImplementationDecl:
2945 return createCXString("ObjCImplementationDecl");
2946 case CXCursor_ObjCCategoryImplDecl:
2947 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00002948 case CXCursor_CXXMethod:
2949 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00002950 case CXCursor_UnexposedDecl:
2951 return createCXString("UnexposedDecl");
2952 case CXCursor_ObjCSuperClassRef:
2953 return createCXString("ObjCSuperClassRef");
2954 case CXCursor_ObjCProtocolRef:
2955 return createCXString("ObjCProtocolRef");
2956 case CXCursor_ObjCClassRef:
2957 return createCXString("ObjCClassRef");
2958 case CXCursor_TypeRef:
2959 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00002960 case CXCursor_TemplateRef:
2961 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00002962 case CXCursor_NamespaceRef:
2963 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00002964 case CXCursor_MemberRef:
2965 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00002966 case CXCursor_LabelRef:
2967 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00002968 case CXCursor_OverloadedDeclRef:
2969 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00002970 case CXCursor_UnexposedExpr:
2971 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00002972 case CXCursor_BlockExpr:
2973 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00002974 case CXCursor_DeclRefExpr:
2975 return createCXString("DeclRefExpr");
2976 case CXCursor_MemberRefExpr:
2977 return createCXString("MemberRefExpr");
2978 case CXCursor_CallExpr:
2979 return createCXString("CallExpr");
2980 case CXCursor_ObjCMessageExpr:
2981 return createCXString("ObjCMessageExpr");
2982 case CXCursor_UnexposedStmt:
2983 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00002984 case CXCursor_LabelStmt:
2985 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00002986 case CXCursor_InvalidFile:
2987 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00002988 case CXCursor_InvalidCode:
2989 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00002990 case CXCursor_NoDeclFound:
2991 return createCXString("NoDeclFound");
2992 case CXCursor_NotImplemented:
2993 return createCXString("NotImplemented");
2994 case CXCursor_TranslationUnit:
2995 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00002996 case CXCursor_UnexposedAttr:
2997 return createCXString("UnexposedAttr");
2998 case CXCursor_IBActionAttr:
2999 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003000 case CXCursor_IBOutletAttr:
3001 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003002 case CXCursor_IBOutletCollectionAttr:
3003 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003004 case CXCursor_PreprocessingDirective:
3005 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003006 case CXCursor_MacroDefinition:
3007 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003008 case CXCursor_MacroInstantiation:
3009 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003010 case CXCursor_InclusionDirective:
3011 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003012 case CXCursor_Namespace:
3013 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003014 case CXCursor_LinkageSpec:
3015 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003016 case CXCursor_CXXBaseSpecifier:
3017 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003018 case CXCursor_Constructor:
3019 return createCXString("CXXConstructor");
3020 case CXCursor_Destructor:
3021 return createCXString("CXXDestructor");
3022 case CXCursor_ConversionFunction:
3023 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003024 case CXCursor_TemplateTypeParameter:
3025 return createCXString("TemplateTypeParameter");
3026 case CXCursor_NonTypeTemplateParameter:
3027 return createCXString("NonTypeTemplateParameter");
3028 case CXCursor_TemplateTemplateParameter:
3029 return createCXString("TemplateTemplateParameter");
3030 case CXCursor_FunctionTemplate:
3031 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003032 case CXCursor_ClassTemplate:
3033 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003034 case CXCursor_ClassTemplatePartialSpecialization:
3035 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003036 case CXCursor_NamespaceAlias:
3037 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003038 case CXCursor_UsingDirective:
3039 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003040 case CXCursor_UsingDeclaration:
3041 return createCXString("UsingDeclaration");
Steve Naroff89922f82009-08-31 00:59:03 +00003042 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003043
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003044 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003045 return createCXString(NULL);
Steve Naroff600866c2009-08-27 19:51:58 +00003046}
Steve Naroff89922f82009-08-31 00:59:03 +00003047
Ted Kremeneke68fff62010-02-17 00:41:32 +00003048enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3049 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003050 CXClientData client_data) {
3051 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003052
3053 // If our current best cursor is the construction of a temporary object,
3054 // don't replace that cursor with a type reference, because we want
3055 // clang_getCursor() to point at the constructor.
3056 if (clang_isExpression(BestCursor->kind) &&
3057 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3058 cursor.kind == CXCursor_TypeRef)
3059 return CXChildVisit_Recurse;
3060
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003061 *BestCursor = cursor;
3062 return CXChildVisit_Recurse;
3063}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003064
Douglas Gregorb9790342010-01-22 21:44:22 +00003065CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3066 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003067 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003068
Douglas Gregorb9790342010-01-22 21:44:22 +00003069 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003070 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3071
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003072 // Translate the given source location to make it point at the beginning of
3073 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003074 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003075
3076 // Guard against an invalid SourceLocation, or we may assert in one
3077 // of the following calls.
3078 if (SLoc.isInvalid())
3079 return clang_getNullCursor();
3080
Douglas Gregor40749ee2010-11-03 00:35:38 +00003081 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003082 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3083 CXXUnit->getASTContext().getLangOptions());
3084
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003085 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3086 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003087 // FIXME: Would be great to have a "hint" cursor, then walk from that
3088 // hint cursor upward until we find a cursor whose source range encloses
3089 // the region of interest, rather than starting from the translation unit.
3090 CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit);
Ted Kremeneke68fff62010-02-17 00:41:32 +00003091 CursorVisitor CursorVis(CXXUnit, GetCursorVisitor, &Result,
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003092 Decl::MaxPCHLevel, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003093 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003094 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003095
3096 if (Logging) {
3097 CXFile SearchFile;
3098 unsigned SearchLine, SearchColumn;
3099 CXFile ResultFile;
3100 unsigned ResultLine, ResultColumn;
3101 CXString SearchFileName, ResultFileName, KindSpelling;
3102 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3103
3104 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3105 0);
3106 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3107 &ResultColumn, 0);
3108 SearchFileName = clang_getFileName(SearchFile);
3109 ResultFileName = clang_getFileName(ResultFile);
3110 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3111 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d)\n",
3112 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3113 clang_getCString(KindSpelling),
3114 clang_getCString(ResultFileName), ResultLine, ResultColumn);
3115 clang_disposeString(SearchFileName);
3116 clang_disposeString(ResultFileName);
3117 clang_disposeString(KindSpelling);
3118 }
3119
Ted Kremeneke68fff62010-02-17 00:41:32 +00003120 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003121}
3122
Ted Kremenek73885552009-11-17 19:28:59 +00003123CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003124 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003125}
3126
3127unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003128 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003129}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003130
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003131unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003132 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3133}
3134
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003135unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003136 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3137}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003138
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003139unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003140 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3141}
3142
Douglas Gregor97b98722010-01-19 23:20:36 +00003143unsigned clang_isExpression(enum CXCursorKind K) {
3144 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3145}
3146
3147unsigned clang_isStatement(enum CXCursorKind K) {
3148 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3149}
3150
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003151unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3152 return K == CXCursor_TranslationUnit;
3153}
3154
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003155unsigned clang_isPreprocessing(enum CXCursorKind K) {
3156 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3157}
3158
Ted Kremenekad6eff62010-03-08 21:17:29 +00003159unsigned clang_isUnexposed(enum CXCursorKind K) {
3160 switch (K) {
3161 case CXCursor_UnexposedDecl:
3162 case CXCursor_UnexposedExpr:
3163 case CXCursor_UnexposedStmt:
3164 case CXCursor_UnexposedAttr:
3165 return true;
3166 default:
3167 return false;
3168 }
3169}
3170
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003171CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003172 return C.kind;
3173}
3174
Douglas Gregor98258af2010-01-18 22:46:11 +00003175CXSourceLocation clang_getCursorLocation(CXCursor C) {
3176 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003177 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003178 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003179 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3180 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003181 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003182 }
3183
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003184 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003185 std::pair<ObjCProtocolDecl *, SourceLocation> P
3186 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003187 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003188 }
3189
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003190 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003191 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3192 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003193 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003194 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003195
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003196 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003197 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003198 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003199 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003200
3201 case CXCursor_TemplateRef: {
3202 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3203 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3204 }
3205
Douglas Gregor69319002010-08-31 23:48:11 +00003206 case CXCursor_NamespaceRef: {
3207 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3208 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3209 }
3210
Douglas Gregora67e03f2010-09-09 21:42:20 +00003211 case CXCursor_MemberRef: {
3212 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3213 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3214 }
3215
Ted Kremenek3064ef92010-08-27 21:34:58 +00003216 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003217 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3218 if (!BaseSpec)
3219 return clang_getNullLocation();
3220
3221 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3222 return cxloc::translateSourceLocation(getCursorContext(C),
3223 TSInfo->getTypeLoc().getBeginLoc());
3224
3225 return cxloc::translateSourceLocation(getCursorContext(C),
3226 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003227 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003228
Douglas Gregor36897b02010-09-10 00:22:18 +00003229 case CXCursor_LabelRef: {
3230 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3231 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3232 }
3233
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003234 case CXCursor_OverloadedDeclRef:
3235 return cxloc::translateSourceLocation(getCursorContext(C),
3236 getCursorOverloadedDeclRef(C).second);
3237
Douglas Gregorf46034a2010-01-18 23:41:10 +00003238 default:
3239 // FIXME: Need a way to enumerate all non-reference cases.
3240 llvm_unreachable("Missed a reference kind");
3241 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003242 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003243
3244 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003245 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003246 getLocationFromExpr(getCursorExpr(C)));
3247
Douglas Gregor36897b02010-09-10 00:22:18 +00003248 if (clang_isStatement(C.kind))
3249 return cxloc::translateSourceLocation(getCursorContext(C),
3250 getCursorStmt(C)->getLocStart());
3251
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003252 if (C.kind == CXCursor_PreprocessingDirective) {
3253 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3254 return cxloc::translateSourceLocation(getCursorContext(C), L);
3255 }
Douglas Gregor48072312010-03-18 15:23:44 +00003256
3257 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003258 SourceLocation L
3259 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003260 return cxloc::translateSourceLocation(getCursorContext(C), L);
3261 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003262
3263 if (C.kind == CXCursor_MacroDefinition) {
3264 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3265 return cxloc::translateSourceLocation(getCursorContext(C), L);
3266 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003267
3268 if (C.kind == CXCursor_InclusionDirective) {
3269 SourceLocation L
3270 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3271 return cxloc::translateSourceLocation(getCursorContext(C), L);
3272 }
3273
Ted Kremenek9a700d22010-05-12 06:16:13 +00003274 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003275 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003276
Douglas Gregorf46034a2010-01-18 23:41:10 +00003277 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003278 SourceLocation Loc = D->getLocation();
3279 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3280 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003281 // FIXME: Multiple variables declared in a single declaration
3282 // currently lack the information needed to correctly determine their
3283 // ranges when accounting for the type-specifier. We use context
3284 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3285 // and if so, whether it is the first decl.
3286 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3287 if (!cxcursor::isFirstInDeclGroup(C))
3288 Loc = VD->getLocation();
3289 }
3290
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003291 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003292}
Douglas Gregora7bde202010-01-19 00:34:46 +00003293
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003294} // end extern "C"
3295
3296static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003297 if (clang_isReference(C.kind)) {
3298 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003299 case CXCursor_ObjCSuperClassRef:
3300 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003301
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003302 case CXCursor_ObjCProtocolRef:
3303 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003304
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003305 case CXCursor_ObjCClassRef:
3306 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003307
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003308 case CXCursor_TypeRef:
3309 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003310
3311 case CXCursor_TemplateRef:
3312 return getCursorTemplateRef(C).second;
3313
Douglas Gregor69319002010-08-31 23:48:11 +00003314 case CXCursor_NamespaceRef:
3315 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003316
3317 case CXCursor_MemberRef:
3318 return getCursorMemberRef(C).second;
3319
Ted Kremenek3064ef92010-08-27 21:34:58 +00003320 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003321 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003322
Douglas Gregor36897b02010-09-10 00:22:18 +00003323 case CXCursor_LabelRef:
3324 return getCursorLabelRef(C).second;
3325
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003326 case CXCursor_OverloadedDeclRef:
3327 return getCursorOverloadedDeclRef(C).second;
3328
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003329 default:
3330 // FIXME: Need a way to enumerate all non-reference cases.
3331 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003332 }
3333 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003334
3335 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003336 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003337
3338 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003339 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003340
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003341 if (C.kind == CXCursor_PreprocessingDirective)
3342 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003343
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003344 if (C.kind == CXCursor_MacroInstantiation)
3345 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003346
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003347 if (C.kind == CXCursor_MacroDefinition)
3348 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003349
3350 if (C.kind == CXCursor_InclusionDirective)
3351 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3352
Ted Kremenek007a7c92010-11-01 23:26:51 +00003353 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3354 Decl *D = cxcursor::getCursorDecl(C);
3355 SourceRange R = D->getSourceRange();
3356 // FIXME: Multiple variables declared in a single declaration
3357 // currently lack the information needed to correctly determine their
3358 // ranges when accounting for the type-specifier. We use context
3359 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3360 // and if so, whether it is the first decl.
3361 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3362 if (!cxcursor::isFirstInDeclGroup(C))
3363 R.setBegin(VD->getLocation());
3364 }
3365 return R;
3366 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003367 return SourceRange();}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003368
3369extern "C" {
3370
3371CXSourceRange clang_getCursorExtent(CXCursor C) {
3372 SourceRange R = getRawCursorExtent(C);
3373 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003374 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003375
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003376 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003377}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003378
3379CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003380 if (clang_isInvalid(C.kind))
3381 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003382
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003383 ASTUnit *CXXUnit = getCursorASTUnit(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003384 if (clang_isDeclaration(C.kind)) {
3385 Decl *D = getCursorDecl(C);
3386 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
3387 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), CXXUnit);
3388 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
3389 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), CXXUnit);
3390 if (ObjCForwardProtocolDecl *Protocols
3391 = dyn_cast<ObjCForwardProtocolDecl>(D))
3392 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), CXXUnit);
3393
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003394 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003395 }
3396
Douglas Gregor97b98722010-01-19 23:20:36 +00003397 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003398 Expr *E = getCursorExpr(C);
3399 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003400 if (D)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003401 return MakeCXCursor(D, CXXUnit);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003402
3403 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
3404 return MakeCursorOverloadedDeclRef(Ovl, CXXUnit);
3405
Douglas Gregor97b98722010-01-19 23:20:36 +00003406 return clang_getNullCursor();
3407 }
3408
Douglas Gregor36897b02010-09-10 00:22:18 +00003409 if (clang_isStatement(C.kind)) {
3410 Stmt *S = getCursorStmt(C);
3411 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
3412 return MakeCXCursor(Goto->getLabel(), getCursorDecl(C),
3413 getCursorASTUnit(C));
3414
3415 return clang_getNullCursor();
3416 }
3417
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003418 if (C.kind == CXCursor_MacroInstantiation) {
3419 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
3420 return MakeMacroDefinitionCursor(Def, CXXUnit);
3421 }
3422
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003423 if (!clang_isReference(C.kind))
3424 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003425
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003426 switch (C.kind) {
3427 case CXCursor_ObjCSuperClassRef:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003428 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, CXXUnit);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003429
3430 case CXCursor_ObjCProtocolRef: {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003431 return MakeCXCursor(getCursorObjCProtocolRef(C).first, CXXUnit);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003432
3433 case CXCursor_ObjCClassRef:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003434 return MakeCXCursor(getCursorObjCClassRef(C).first, CXXUnit);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003435
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003436 case CXCursor_TypeRef:
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003437 return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit);
Douglas Gregor0b36e612010-08-31 20:37:03 +00003438
3439 case CXCursor_TemplateRef:
3440 return MakeCXCursor(getCursorTemplateRef(C).first, CXXUnit);
3441
Douglas Gregor69319002010-08-31 23:48:11 +00003442 case CXCursor_NamespaceRef:
3443 return MakeCXCursor(getCursorNamespaceRef(C).first, CXXUnit);
3444
Douglas Gregora67e03f2010-09-09 21:42:20 +00003445 case CXCursor_MemberRef:
3446 return MakeCXCursor(getCursorMemberRef(C).first, CXXUnit);
3447
Ted Kremenek3064ef92010-08-27 21:34:58 +00003448 case CXCursor_CXXBaseSpecifier: {
3449 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3450 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
3451 CXXUnit));
3452 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003453
Douglas Gregor36897b02010-09-10 00:22:18 +00003454 case CXCursor_LabelRef:
3455 // FIXME: We end up faking the "parent" declaration here because we
3456 // don't want to make CXCursor larger.
3457 return MakeCXCursor(getCursorLabelRef(C).first,
3458 CXXUnit->getASTContext().getTranslationUnitDecl(),
3459 CXXUnit);
3460
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003461 case CXCursor_OverloadedDeclRef:
3462 return C;
3463
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003464 default:
3465 // We would prefer to enumerate all non-reference cursor kinds here.
3466 llvm_unreachable("Unhandled reference cursor kind");
3467 break;
3468 }
3469 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003470
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003471 return clang_getNullCursor();
3472}
3473
Douglas Gregorb6998662010-01-19 19:34:47 +00003474CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003475 if (clang_isInvalid(C.kind))
3476 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003477
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003478 ASTUnit *CXXUnit = getCursorASTUnit(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003479
Douglas Gregorb6998662010-01-19 19:34:47 +00003480 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003481 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003482 C = clang_getCursorReferenced(C);
3483 WasReference = true;
3484 }
3485
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003486 if (C.kind == CXCursor_MacroInstantiation)
3487 return clang_getCursorReferenced(C);
3488
Douglas Gregorb6998662010-01-19 19:34:47 +00003489 if (!clang_isDeclaration(C.kind))
3490 return clang_getNullCursor();
3491
3492 Decl *D = getCursorDecl(C);
3493 if (!D)
3494 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003495
Douglas Gregorb6998662010-01-19 19:34:47 +00003496 switch (D->getKind()) {
3497 // Declaration kinds that don't really separate the notions of
3498 // declaration and definition.
3499 case Decl::Namespace:
3500 case Decl::Typedef:
3501 case Decl::TemplateTypeParm:
3502 case Decl::EnumConstant:
3503 case Decl::Field:
3504 case Decl::ObjCIvar:
3505 case Decl::ObjCAtDefsField:
3506 case Decl::ImplicitParam:
3507 case Decl::ParmVar:
3508 case Decl::NonTypeTemplateParm:
3509 case Decl::TemplateTemplateParm:
3510 case Decl::ObjCCategoryImpl:
3511 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003512 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003513 case Decl::LinkageSpec:
3514 case Decl::ObjCPropertyImpl:
3515 case Decl::FileScopeAsm:
3516 case Decl::StaticAssert:
3517 case Decl::Block:
3518 return C;
3519
3520 // Declaration kinds that don't make any sense here, but are
3521 // nonetheless harmless.
3522 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003523 break;
3524
3525 // Declaration kinds for which the definition is not resolvable.
3526 case Decl::UnresolvedUsingTypename:
3527 case Decl::UnresolvedUsingValue:
3528 break;
3529
3530 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003531 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
3532 CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003533
3534 case Decl::NamespaceAlias:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003535 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003536
3537 case Decl::Enum:
3538 case Decl::Record:
3539 case Decl::CXXRecord:
3540 case Decl::ClassTemplateSpecialization:
3541 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003542 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003543 return MakeCXCursor(Def, CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003544 return clang_getNullCursor();
3545
3546 case Decl::Function:
3547 case Decl::CXXMethod:
3548 case Decl::CXXConstructor:
3549 case Decl::CXXDestructor:
3550 case Decl::CXXConversion: {
3551 const FunctionDecl *Def = 0;
3552 if (cast<FunctionDecl>(D)->getBody(Def))
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003553 return MakeCXCursor(const_cast<FunctionDecl *>(Def), CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003554 return clang_getNullCursor();
3555 }
3556
3557 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003558 // Ask the variable if it has a definition.
3559 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
3560 return MakeCXCursor(Def, CXXUnit);
3561 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003562 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003563
Douglas Gregorb6998662010-01-19 19:34:47 +00003564 case Decl::FunctionTemplate: {
3565 const FunctionDecl *Def = 0;
3566 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003567 return MakeCXCursor(Def->getDescribedFunctionTemplate(), CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003568 return clang_getNullCursor();
3569 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003570
Douglas Gregorb6998662010-01-19 19:34:47 +00003571 case Decl::ClassTemplate: {
3572 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003573 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003574 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003575 CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003576 return clang_getNullCursor();
3577 }
3578
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003579 case Decl::Using:
3580 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
3581 D->getLocation(), CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003582
3583 case Decl::UsingShadow:
3584 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003585 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003586 CXXUnit));
Douglas Gregorb6998662010-01-19 19:34:47 +00003587
3588 case Decl::ObjCMethod: {
3589 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3590 if (Method->isThisDeclarationADefinition())
3591 return C;
3592
3593 // Dig out the method definition in the associated
3594 // @implementation, if we have it.
3595 // FIXME: The ASTs should make finding the definition easier.
3596 if (ObjCInterfaceDecl *Class
3597 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3598 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3599 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3600 Method->isInstanceMethod()))
3601 if (Def->isThisDeclarationADefinition())
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003602 return MakeCXCursor(Def, CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003603
3604 return clang_getNullCursor();
3605 }
3606
3607 case Decl::ObjCCategory:
3608 if (ObjCCategoryImplDecl *Impl
3609 = cast<ObjCCategoryDecl>(D)->getImplementation())
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003610 return MakeCXCursor(Impl, CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003611 return clang_getNullCursor();
3612
3613 case Decl::ObjCProtocol:
3614 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3615 return C;
3616 return clang_getNullCursor();
3617
3618 case Decl::ObjCInterface:
3619 // There are two notions of a "definition" for an Objective-C
3620 // class: the interface and its implementation. When we resolved a
3621 // reference to an Objective-C class, produce the @interface as
3622 // the definition; when we were provided with the interface,
3623 // produce the @implementation as the definition.
3624 if (WasReference) {
3625 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
3626 return C;
3627 } else if (ObjCImplementationDecl *Impl
3628 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003629 return MakeCXCursor(Impl, CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003630 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003631
Douglas Gregorb6998662010-01-19 19:34:47 +00003632 case Decl::ObjCProperty:
3633 // FIXME: We don't really know where to find the
3634 // ObjCPropertyImplDecls that implement this property.
3635 return clang_getNullCursor();
3636
3637 case Decl::ObjCCompatibleAlias:
3638 if (ObjCInterfaceDecl *Class
3639 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
3640 if (!Class->isForwardDecl())
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003641 return MakeCXCursor(Class, CXXUnit);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003642
Douglas Gregorb6998662010-01-19 19:34:47 +00003643 return clang_getNullCursor();
3644
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003645 case Decl::ObjCForwardProtocol:
3646 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
3647 D->getLocation(), CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003648
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003649 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00003650 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003651 CXXUnit);
Douglas Gregorb6998662010-01-19 19:34:47 +00003652
3653 case Decl::Friend:
3654 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003655 return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit));
Douglas Gregorb6998662010-01-19 19:34:47 +00003656 return clang_getNullCursor();
3657
3658 case Decl::FriendTemplate:
3659 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003660 return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit));
Douglas Gregorb6998662010-01-19 19:34:47 +00003661 return clang_getNullCursor();
3662 }
3663
3664 return clang_getNullCursor();
3665}
3666
3667unsigned clang_isCursorDefinition(CXCursor C) {
3668 if (!clang_isDeclaration(C.kind))
3669 return 0;
3670
3671 return clang_getCursorDefinition(C) == C;
3672}
3673
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003674unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00003675 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003676 return 0;
3677
3678 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3679 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3680 return E->getNumDecls();
3681
3682 if (OverloadedTemplateStorage *S
3683 = Storage.dyn_cast<OverloadedTemplateStorage*>())
3684 return S->size();
3685
3686 Decl *D = Storage.get<Decl*>();
3687 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00003688 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003689 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
3690 return Classes->size();
3691 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
3692 return Protocols->protocol_size();
3693
3694 return 0;
3695}
3696
3697CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00003698 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003699 return clang_getNullCursor();
3700
3701 if (index >= clang_getNumOverloadedDecls(cursor))
3702 return clang_getNullCursor();
3703
3704 ASTUnit *Unit = getCursorASTUnit(cursor);
3705 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
3706 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3707 return MakeCXCursor(E->decls_begin()[index], Unit);
3708
3709 if (OverloadedTemplateStorage *S
3710 = Storage.dyn_cast<OverloadedTemplateStorage*>())
3711 return MakeCXCursor(S->begin()[index], Unit);
3712
3713 Decl *D = Storage.get<Decl*>();
3714 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
3715 // FIXME: This is, unfortunately, linear time.
3716 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
3717 std::advance(Pos, index);
3718 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), Unit);
3719 }
3720
3721 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
3722 return MakeCXCursor(Classes->begin()[index].getInterface(), Unit);
3723
3724 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
3725 return MakeCXCursor(Protocols->protocol_begin()[index], Unit);
3726
3727 return clang_getNullCursor();
3728}
3729
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003730void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00003731 const char **startBuf,
3732 const char **endBuf,
3733 unsigned *startLine,
3734 unsigned *startColumn,
3735 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003736 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003737 assert(getCursorDecl(C) && "CXCursor has null decl");
3738 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00003739 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
3740 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003741
Steve Naroff4ade6d62009-09-23 17:52:52 +00003742 SourceManager &SM = FD->getASTContext().getSourceManager();
3743 *startBuf = SM.getCharacterData(Body->getLBracLoc());
3744 *endBuf = SM.getCharacterData(Body->getRBracLoc());
3745 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
3746 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
3747 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
3748 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
3749}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003750
Douglas Gregor0a812cf2010-02-18 23:07:20 +00003751void clang_enableStackTraces(void) {
3752 llvm::sys::PrintStackTraceOnErrorSignal();
3753}
3754
Daniel Dunbar995aaf92010-11-04 01:26:29 +00003755void clang_executeOnThread(void (*fn)(void*), void *user_data,
3756 unsigned stack_size) {
3757 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
3758}
3759
Ted Kremenekfb480492010-01-13 21:46:36 +00003760} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00003761
Ted Kremenekfb480492010-01-13 21:46:36 +00003762//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003763// Token-based Operations.
3764//===----------------------------------------------------------------------===//
3765
3766/* CXToken layout:
3767 * int_data[0]: a CXTokenKind
3768 * int_data[1]: starting token location
3769 * int_data[2]: token length
3770 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003771 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003772 * otherwise unused.
3773 */
3774extern "C" {
3775
3776CXTokenKind clang_getTokenKind(CXToken CXTok) {
3777 return static_cast<CXTokenKind>(CXTok.int_data[0]);
3778}
3779
3780CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
3781 switch (clang_getTokenKind(CXTok)) {
3782 case CXToken_Identifier:
3783 case CXToken_Keyword:
3784 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003785 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
3786 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003787
3788 case CXToken_Literal: {
3789 // We have stashed the starting pointer in the ptr_data field. Use it.
3790 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003791 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003792 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003793
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003794 case CXToken_Punctuation:
3795 case CXToken_Comment:
3796 break;
3797 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003798
3799 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003800 // deconstructing the source location.
3801 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
3802 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003803 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003804
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003805 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
3806 std::pair<FileID, unsigned> LocInfo
3807 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00003808 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00003809 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00003810 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
3811 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00003812 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003813
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00003814 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003815}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003816
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003817CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
3818 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
3819 if (!CXXUnit)
3820 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003821
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003822 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
3823 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
3824}
3825
3826CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
3827 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
Douglas Gregor5352ac02010-01-28 00:27:43 +00003828 if (!CXXUnit)
3829 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003830
3831 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003832 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
3833}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003834
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003835void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
3836 CXToken **Tokens, unsigned *NumTokens) {
3837 if (Tokens)
3838 *Tokens = 0;
3839 if (NumTokens)
3840 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003841
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003842 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
3843 if (!CXXUnit || !Tokens || !NumTokens)
3844 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003845
Douglas Gregorbdf60622010-03-05 21:16:25 +00003846 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3847
Daniel Dunbar85b988f2010-02-14 08:31:57 +00003848 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003849 if (R.isInvalid())
3850 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003851
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003852 SourceManager &SourceMgr = CXXUnit->getSourceManager();
3853 std::pair<FileID, unsigned> BeginLocInfo
3854 = SourceMgr.getDecomposedLoc(R.getBegin());
3855 std::pair<FileID, unsigned> EndLocInfo
3856 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003857
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003858 // Cannot tokenize across files.
3859 if (BeginLocInfo.first != EndLocInfo.first)
3860 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003861
3862 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00003863 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00003864 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00003865 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00003866 if (Invalid)
3867 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00003868
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003869 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
3870 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00003871 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003872 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003873
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003874 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00003875 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003876 llvm::SmallVector<CXToken, 32> CXTokens;
3877 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00003878 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003879 do {
3880 // Lex the next token
3881 Lex.LexFromRawLexer(Tok);
3882 if (Tok.is(tok::eof))
3883 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003884
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003885 // Initialize the CXToken.
3886 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003887
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003888 // - Common fields
3889 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
3890 CXTok.int_data[2] = Tok.getLength();
3891 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003892
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003893 // - Kind-specific fields
3894 if (Tok.isLiteral()) {
3895 CXTok.int_data[0] = CXToken_Literal;
3896 CXTok.ptr_data = (void *)Tok.getLiteralData();
3897 } else if (Tok.is(tok::identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00003898 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003899 std::pair<FileID, unsigned> LocInfo
3900 = SourceMgr.getDecomposedLoc(Tok.getLocation());
Douglas Gregorf715ca12010-03-16 00:06:06 +00003901 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00003902 llvm::StringRef Buf
Douglas Gregorf715ca12010-03-16 00:06:06 +00003903 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
3904 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00003905 return;
3906
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00003907 const char *StartPos = Buf.data() + LocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003908 IdentifierInfo *II
3909 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok, StartPos);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00003910
David Chisnall096428b2010-10-13 21:44:48 +00003911 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00003912 CXTok.int_data[0] = CXToken_Keyword;
3913 }
3914 else {
3915 CXTok.int_data[0] = II->getTokenID() == tok::identifier?
3916 CXToken_Identifier
3917 : CXToken_Keyword;
3918 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003919 CXTok.ptr_data = II;
3920 } else if (Tok.is(tok::comment)) {
3921 CXTok.int_data[0] = CXToken_Comment;
3922 CXTok.ptr_data = 0;
3923 } else {
3924 CXTok.int_data[0] = CXToken_Punctuation;
3925 CXTok.ptr_data = 0;
3926 }
3927 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00003928 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003929 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003930
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003931 if (CXTokens.empty())
3932 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003933
Douglas Gregorfc8ea232010-01-26 17:06:03 +00003934 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
3935 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
3936 *NumTokens = CXTokens.size();
3937}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00003938
Ted Kremenek6db61092010-05-05 00:55:15 +00003939void clang_disposeTokens(CXTranslationUnit TU,
3940 CXToken *Tokens, unsigned NumTokens) {
3941 free(Tokens);
3942}
3943
3944} // end: extern "C"
3945
3946//===----------------------------------------------------------------------===//
3947// Token annotation APIs.
3948//===----------------------------------------------------------------------===//
3949
Douglas Gregor0045e9f2010-01-26 18:31:56 +00003950typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00003951static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
3952 CXCursor parent,
3953 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00003954namespace {
3955class AnnotateTokensWorker {
3956 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00003957 CXToken *Tokens;
3958 CXCursor *Cursors;
3959 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00003960 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00003961 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00003962 CursorVisitor AnnotateVis;
3963 SourceManager &SrcMgr;
3964
3965 bool MoreTokens() const { return TokIdx < NumTokens; }
3966 unsigned NextToken() const { return TokIdx; }
3967 void AdvanceToken() { ++TokIdx; }
3968 SourceLocation GetTokenLoc(unsigned tokI) {
3969 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
3970 }
3971
Ted Kremenek6db61092010-05-05 00:55:15 +00003972public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00003973 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00003974 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
3975 ASTUnit *CXXUnit, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00003976 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00003977 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00003978 AnnotateVis(CXXUnit, AnnotateTokensVisitor, this,
3979 Decl::MaxPCHLevel, RegionOfInterest),
3980 SrcMgr(CXXUnit->getSourceManager()) {}
Ted Kremenek11949cb2010-05-05 00:55:17 +00003981
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00003982 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00003983 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00003984 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00003985 void AnnotateTokens() {
3986 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getASTUnit()));
3987 }
Ted Kremenek6db61092010-05-05 00:55:15 +00003988};
3989}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00003990
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00003991void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
3992 // Walk the AST within the region of interest, annotating tokens
3993 // along the way.
3994 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00003995
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00003996 for (unsigned I = 0 ; I < TokIdx ; ++I) {
3997 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00003998 if (Pos != Annotated.end() &&
3999 (clang_isInvalid(Cursors[I].kind) ||
4000 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004001 Cursors[I] = Pos->second;
4002 }
4003
4004 // Finish up annotating any tokens left.
4005 if (!MoreTokens())
4006 return;
4007
4008 const CXCursor &C = clang_getNullCursor();
4009 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4010 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4011 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004012 }
4013}
4014
Ted Kremenek6db61092010-05-05 00:55:15 +00004015enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004016AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004017 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004018 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004019 if (cursorRange.isInvalid())
4020 return CXChildVisit_Recurse;
4021
Douglas Gregor4419b672010-10-21 06:10:04 +00004022 if (clang_isPreprocessing(cursor.kind)) {
4023 // For macro instantiations, just note where the beginning of the macro
4024 // instantiation occurs.
4025 if (cursor.kind == CXCursor_MacroInstantiation) {
4026 Annotated[Loc.int_data] = cursor;
4027 return CXChildVisit_Recurse;
4028 }
4029
Douglas Gregor4419b672010-10-21 06:10:04 +00004030 // Items in the preprocessing record are kept separate from items in
4031 // declarations, so we keep a separate token index.
4032 unsigned SavedTokIdx = TokIdx;
4033 TokIdx = PreprocessingTokIdx;
4034
4035 // Skip tokens up until we catch up to the beginning of the preprocessing
4036 // entry.
4037 while (MoreTokens()) {
4038 const unsigned I = NextToken();
4039 SourceLocation TokLoc = GetTokenLoc(I);
4040 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4041 case RangeBefore:
4042 AdvanceToken();
4043 continue;
4044 case RangeAfter:
4045 case RangeOverlap:
4046 break;
4047 }
4048 break;
4049 }
4050
4051 // Look at all of the tokens within this range.
4052 while (MoreTokens()) {
4053 const unsigned I = NextToken();
4054 SourceLocation TokLoc = GetTokenLoc(I);
4055 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4056 case RangeBefore:
4057 assert(0 && "Infeasible");
4058 case RangeAfter:
4059 break;
4060 case RangeOverlap:
4061 Cursors[I] = cursor;
4062 AdvanceToken();
4063 continue;
4064 }
4065 break;
4066 }
4067
4068 // Save the preprocessing token index; restore the non-preprocessing
4069 // token index.
4070 PreprocessingTokIdx = TokIdx;
4071 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004072 return CXChildVisit_Recurse;
4073 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004074
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004075 if (cursorRange.isInvalid())
4076 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004077
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004078 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4079
Ted Kremeneka333c662010-05-12 05:29:33 +00004080 // Adjust the annotated range based specific declarations.
4081 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4082 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004083 Decl *D = cxcursor::getCursorDecl(cursor);
4084 // Don't visit synthesized ObjC methods, since they have no syntatic
4085 // representation in the source.
4086 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4087 if (MD->isSynthesized())
4088 return CXChildVisit_Continue;
4089 }
4090 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Ted Kremeneka333c662010-05-12 05:29:33 +00004091 if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) {
4092 TypeLoc TL = TI->getTypeLoc();
Abramo Bagnarabd054db2010-05-20 10:00:11 +00004093 SourceLocation TLoc = TL.getSourceRange().getBegin();
Douglas Gregor81d3c042010-11-01 20:13:04 +00004094 if (TLoc.isValid() && L.isValid() &&
Ted Kremenek6bfd5332010-05-13 15:38:38 +00004095 SrcMgr.isBeforeInTranslationUnit(TLoc, L))
Ted Kremeneka333c662010-05-12 05:29:33 +00004096 cursorRange.setBegin(TLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004097 }
4098 }
4099 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004100
Ted Kremenek3f404602010-08-14 01:14:06 +00004101 // If the location of the cursor occurs within a macro instantiation, record
4102 // the spelling location of the cursor in our annotation map. We can then
4103 // paper over the token labelings during a post-processing step to try and
4104 // get cursor mappings for tokens that are the *arguments* of a macro
4105 // instantiation.
4106 if (L.isMacroID()) {
4107 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4108 // Only invalidate the old annotation if it isn't part of a preprocessing
4109 // directive. Here we assume that the default construction of CXCursor
4110 // results in CXCursor.kind being an initialized value (i.e., 0). If
4111 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004112
Ted Kremenek3f404602010-08-14 01:14:06 +00004113 CXCursor &oldC = Annotated[rawEncoding];
4114 if (!clang_isPreprocessing(oldC.kind))
4115 oldC = cursor;
4116 }
4117
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004118 const enum CXCursorKind K = clang_getCursorKind(parent);
4119 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004120 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4121 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004122
4123 while (MoreTokens()) {
4124 const unsigned I = NextToken();
4125 SourceLocation TokLoc = GetTokenLoc(I);
4126 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4127 case RangeBefore:
4128 Cursors[I] = updateC;
4129 AdvanceToken();
4130 continue;
4131 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004132 case RangeOverlap:
4133 break;
4134 }
4135 break;
4136 }
4137
4138 // Visit children to get their cursor information.
4139 const unsigned BeforeChildren = NextToken();
4140 VisitChildren(cursor);
4141 const unsigned AfterChildren = NextToken();
4142
4143 // Adjust 'Last' to the last token within the extent of the cursor.
4144 while (MoreTokens()) {
4145 const unsigned I = NextToken();
4146 SourceLocation TokLoc = GetTokenLoc(I);
4147 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4148 case RangeBefore:
4149 assert(0 && "Infeasible");
4150 case RangeAfter:
4151 break;
4152 case RangeOverlap:
4153 Cursors[I] = updateC;
4154 AdvanceToken();
4155 continue;
4156 }
4157 break;
4158 }
4159 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004160
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004161 // Scan the tokens that are at the beginning of the cursor, but are not
4162 // capture by the child cursors.
4163
4164 // For AST elements within macros, rely on a post-annotate pass to
4165 // to correctly annotate the tokens with cursors. Otherwise we can
4166 // get confusing results of having tokens that map to cursors that really
4167 // are expanded by an instantiation.
4168 if (L.isMacroID())
4169 cursor = clang_getNullCursor();
4170
4171 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4172 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4173 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004174
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004175 Cursors[I] = cursor;
4176 }
4177 // Scan the tokens that are at the end of the cursor, but are not captured
4178 // but the child cursors.
4179 for (unsigned I = AfterChildren; I != Last; ++I)
4180 Cursors[I] = cursor;
4181
4182 TokIdx = Last;
4183 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004184}
4185
Ted Kremenek6db61092010-05-05 00:55:15 +00004186static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4187 CXCursor parent,
4188 CXClientData client_data) {
4189 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4190}
4191
Ted Kremenekab979612010-11-11 08:05:23 +00004192// This gets run a separate thread to avoid stack blowout.
4193static void runAnnotateTokensWorker(void *UserData) {
4194 ((AnnotateTokensWorker*)UserData)->AnnotateTokens();
4195}
4196
Ted Kremenek6db61092010-05-05 00:55:15 +00004197extern "C" {
4198
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004199void clang_annotateTokens(CXTranslationUnit TU,
4200 CXToken *Tokens, unsigned NumTokens,
4201 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004202
4203 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004204 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004205
Douglas Gregor4419b672010-10-21 06:10:04 +00004206 // Any token we don't specifically annotate will have a NULL cursor.
4207 CXCursor C = clang_getNullCursor();
4208 for (unsigned I = 0; I != NumTokens; ++I)
4209 Cursors[I] = C;
4210
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004211 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
Douglas Gregor4419b672010-10-21 06:10:04 +00004212 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004213 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004214
Douglas Gregorbdf60622010-03-05 21:16:25 +00004215 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004216
Douglas Gregor0396f462010-03-19 05:22:59 +00004217 // Determine the region of interest, which contains all of the tokens.
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004218 SourceRange RegionOfInterest;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004219 RegionOfInterest.setBegin(cxloc::translateSourceLocation(
4220 clang_getTokenLocation(TU, Tokens[0])));
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00004221 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
4222 clang_getTokenLocation(TU,
4223 Tokens[NumTokens - 1])));
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004224
Douglas Gregor0396f462010-03-19 05:22:59 +00004225 // A mapping from the source locations found when re-lexing or traversing the
4226 // region of interest to the corresponding cursors.
4227 AnnotateTokensData Annotated;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004228
4229 // Relex the tokens within the source range to look for preprocessing
Douglas Gregor0396f462010-03-19 05:22:59 +00004230 // directives.
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004231 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4232 std::pair<FileID, unsigned> BeginLocInfo
4233 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4234 std::pair<FileID, unsigned> EndLocInfo
4235 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004236
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004237 llvm::StringRef Buffer;
Douglas Gregor0396f462010-03-19 05:22:59 +00004238 bool Invalid = false;
4239 if (BeginLocInfo.first == EndLocInfo.first &&
4240 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4241 !Invalid) {
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004242 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4243 CXXUnit->getASTContext().getLangOptions(),
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004244 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
Douglas Gregor4ae8f292010-03-18 17:52:52 +00004245 Buffer.end());
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004246 Lex.SetCommentRetentionState(true);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004247
4248 // Lex tokens in raw mode until we hit the end of the range, to avoid
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004249 // entering #includes or expanding macros.
Douglas Gregor48072312010-03-18 15:23:44 +00004250 while (true) {
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004251 Token Tok;
4252 Lex.LexFromRawLexer(Tok);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004253
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004254 reprocess:
4255 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4256 // We have found a preprocessing directive. Gobble it up so that we
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004257 // don't see it while preprocessing these tokens later, but keep track
4258 // of all of the token locations inside this preprocessing directive so
4259 // that we can annotate them appropriately.
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004260 //
4261 // FIXME: Some simple tests here could identify macro definitions and
4262 // #undefs, to provide specific cursor kinds for those.
4263 std::vector<SourceLocation> Locations;
4264 do {
4265 Locations.push_back(Tok.getLocation());
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004266 Lex.LexFromRawLexer(Tok);
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004267 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004268
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004269 using namespace cxcursor;
4270 CXCursor Cursor
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004271 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4272 Locations.back()),
Ted Kremenek6db61092010-05-05 00:55:15 +00004273 CXXUnit);
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004274 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4275 Annotated[Locations[I].getRawEncoding()] = Cursor;
4276 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004277
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004278 if (Tok.isAtStartOfLine())
4279 goto reprocess;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004280
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004281 continue;
4282 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004283
Douglas Gregor48072312010-03-18 15:23:44 +00004284 if (Tok.is(tok::eof))
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004285 break;
4286 }
Douglas Gregor4ae8f292010-03-18 17:52:52 +00004287 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004288
Douglas Gregor0396f462010-03-19 05:22:59 +00004289 // Annotate all of the source locations in the region of interest that map to
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004290 // a specific cursor.
4291 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4292 CXXUnit, RegionOfInterest);
Ted Kremenekab979612010-11-11 08:05:23 +00004293
4294 // Run the worker within a CrashRecoveryContext.
4295 llvm::CrashRecoveryContext CRC;
4296 if (!RunSafely(CRC, runAnnotateTokensWorker, &W)) {
4297 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4298 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004299}
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004300} // end: extern "C"
4301
4302//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004303// Operations for querying linkage of a cursor.
4304//===----------------------------------------------------------------------===//
4305
4306extern "C" {
4307CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004308 if (!clang_isDeclaration(cursor.kind))
4309 return CXLinkage_Invalid;
4310
Ted Kremenek16b42592010-03-03 06:36:57 +00004311 Decl *D = cxcursor::getCursorDecl(cursor);
4312 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4313 switch (ND->getLinkage()) {
4314 case NoLinkage: return CXLinkage_NoLinkage;
4315 case InternalLinkage: return CXLinkage_Internal;
4316 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4317 case ExternalLinkage: return CXLinkage_External;
4318 };
4319
4320 return CXLinkage_Invalid;
4321}
4322} // end: extern "C"
4323
4324//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004325// Operations for querying language of a cursor.
4326//===----------------------------------------------------------------------===//
4327
4328static CXLanguageKind getDeclLanguage(const Decl *D) {
4329 switch (D->getKind()) {
4330 default:
4331 break;
4332 case Decl::ImplicitParam:
4333 case Decl::ObjCAtDefsField:
4334 case Decl::ObjCCategory:
4335 case Decl::ObjCCategoryImpl:
4336 case Decl::ObjCClass:
4337 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004338 case Decl::ObjCForwardProtocol:
4339 case Decl::ObjCImplementation:
4340 case Decl::ObjCInterface:
4341 case Decl::ObjCIvar:
4342 case Decl::ObjCMethod:
4343 case Decl::ObjCProperty:
4344 case Decl::ObjCPropertyImpl:
4345 case Decl::ObjCProtocol:
4346 return CXLanguage_ObjC;
4347 case Decl::CXXConstructor:
4348 case Decl::CXXConversion:
4349 case Decl::CXXDestructor:
4350 case Decl::CXXMethod:
4351 case Decl::CXXRecord:
4352 case Decl::ClassTemplate:
4353 case Decl::ClassTemplatePartialSpecialization:
4354 case Decl::ClassTemplateSpecialization:
4355 case Decl::Friend:
4356 case Decl::FriendTemplate:
4357 case Decl::FunctionTemplate:
4358 case Decl::LinkageSpec:
4359 case Decl::Namespace:
4360 case Decl::NamespaceAlias:
4361 case Decl::NonTypeTemplateParm:
4362 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004363 case Decl::TemplateTemplateParm:
4364 case Decl::TemplateTypeParm:
4365 case Decl::UnresolvedUsingTypename:
4366 case Decl::UnresolvedUsingValue:
4367 case Decl::Using:
4368 case Decl::UsingDirective:
4369 case Decl::UsingShadow:
4370 return CXLanguage_CPlusPlus;
4371 }
4372
4373 return CXLanguage_C;
4374}
4375
4376extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004377
4378enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4379 if (clang_isDeclaration(cursor.kind))
4380 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
4381 if (D->hasAttr<UnavailableAttr>() ||
4382 (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()))
4383 return CXAvailability_Available;
4384
4385 if (D->hasAttr<DeprecatedAttr>())
4386 return CXAvailability_Deprecated;
4387 }
4388
4389 return CXAvailability_Available;
4390}
4391
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004392CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4393 if (clang_isDeclaration(cursor.kind))
4394 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4395
4396 return CXLanguage_Invalid;
4397}
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004398
4399CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4400 if (clang_isDeclaration(cursor.kind)) {
4401 if (Decl *D = getCursorDecl(cursor)) {
4402 DeclContext *DC = D->getDeclContext();
4403 return MakeCXCursor(cast<Decl>(DC), getCursorASTUnit(cursor));
4404 }
4405 }
4406
4407 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4408 if (Decl *D = getCursorDecl(cursor))
4409 return MakeCXCursor(D, getCursorASTUnit(cursor));
4410 }
4411
4412 return clang_getNullCursor();
4413}
4414
4415CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4416 if (clang_isDeclaration(cursor.kind)) {
4417 if (Decl *D = getCursorDecl(cursor)) {
4418 DeclContext *DC = D->getLexicalDeclContext();
4419 return MakeCXCursor(cast<Decl>(DC), getCursorASTUnit(cursor));
4420 }
4421 }
4422
4423 // FIXME: Note that we can't easily compute the lexical context of a
4424 // statement or expression, so we return nothing.
4425 return clang_getNullCursor();
4426}
4427
Douglas Gregor9f592342010-10-01 20:25:15 +00004428static void CollectOverriddenMethods(DeclContext *Ctx,
4429 ObjCMethodDecl *Method,
4430 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
4431 if (!Ctx)
4432 return;
4433
4434 // If we have a class or category implementation, jump straight to the
4435 // interface.
4436 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
4437 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
4438
4439 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
4440 if (!Container)
4441 return;
4442
4443 // Check whether we have a matching method at this level.
4444 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
4445 Method->isInstanceMethod()))
4446 if (Method != Overridden) {
4447 // We found an override at this level; there is no need to look
4448 // into other protocols or categories.
4449 Methods.push_back(Overridden);
4450 return;
4451 }
4452
4453 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4454 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
4455 PEnd = Protocol->protocol_end();
4456 P != PEnd; ++P)
4457 CollectOverriddenMethods(*P, Method, Methods);
4458 }
4459
4460 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4461 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
4462 PEnd = Category->protocol_end();
4463 P != PEnd; ++P)
4464 CollectOverriddenMethods(*P, Method, Methods);
4465 }
4466
4467 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
4468 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
4469 PEnd = Interface->protocol_end();
4470 P != PEnd; ++P)
4471 CollectOverriddenMethods(*P, Method, Methods);
4472
4473 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
4474 Category; Category = Category->getNextClassCategory())
4475 CollectOverriddenMethods(Category, Method, Methods);
4476
4477 // We only look into the superclass if we haven't found anything yet.
4478 if (Methods.empty())
4479 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
4480 return CollectOverriddenMethods(Super, Method, Methods);
4481 }
4482}
4483
4484void clang_getOverriddenCursors(CXCursor cursor,
4485 CXCursor **overridden,
4486 unsigned *num_overridden) {
4487 if (overridden)
4488 *overridden = 0;
4489 if (num_overridden)
4490 *num_overridden = 0;
4491 if (!overridden || !num_overridden)
4492 return;
4493
4494 if (!clang_isDeclaration(cursor.kind))
4495 return;
4496
4497 Decl *D = getCursorDecl(cursor);
4498 if (!D)
4499 return;
4500
4501 // Handle C++ member functions.
4502 ASTUnit *CXXUnit = getCursorASTUnit(cursor);
4503 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
4504 *num_overridden = CXXMethod->size_overridden_methods();
4505 if (!*num_overridden)
4506 return;
4507
4508 *overridden = new CXCursor [*num_overridden];
4509 unsigned I = 0;
4510 for (CXXMethodDecl::method_iterator
4511 M = CXXMethod->begin_overridden_methods(),
4512 MEnd = CXXMethod->end_overridden_methods();
4513 M != MEnd; (void)++M, ++I)
4514 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), CXXUnit);
4515 return;
4516 }
4517
4518 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
4519 if (!Method)
4520 return;
4521
4522 // Handle Objective-C methods.
4523 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
4524 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
4525
4526 if (Methods.empty())
4527 return;
4528
4529 *num_overridden = Methods.size();
4530 *overridden = new CXCursor [Methods.size()];
4531 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
4532 (*overridden)[I] = MakeCXCursor(Methods[I], CXXUnit);
4533}
4534
4535void clang_disposeOverriddenCursors(CXCursor *overridden) {
4536 delete [] overridden;
4537}
4538
Douglas Gregorecdcb882010-10-20 22:00:55 +00004539CXFile clang_getIncludedFile(CXCursor cursor) {
4540 if (cursor.kind != CXCursor_InclusionDirective)
4541 return 0;
4542
4543 InclusionDirective *ID = getCursorInclusionDirective(cursor);
4544 return (void *)ID->getFile();
4545}
4546
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004547} // end: extern "C"
4548
Ted Kremenek9ada39a2010-05-17 20:06:56 +00004549
4550//===----------------------------------------------------------------------===//
4551// C++ AST instrospection.
4552//===----------------------------------------------------------------------===//
4553
4554extern "C" {
4555unsigned clang_CXXMethod_isStatic(CXCursor C) {
4556 if (!clang_isDeclaration(C.kind))
4557 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00004558
4559 CXXMethodDecl *Method = 0;
4560 Decl *D = cxcursor::getCursorDecl(C);
4561 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
4562 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
4563 else
4564 Method = dyn_cast_or_null<CXXMethodDecl>(D);
4565 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00004566}
Ted Kremenekb12903e2010-05-18 22:32:15 +00004567
Ted Kremenek9ada39a2010-05-17 20:06:56 +00004568} // end: extern "C"
4569
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004570//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00004571// Attribute introspection.
4572//===----------------------------------------------------------------------===//
4573
4574extern "C" {
4575CXType clang_getIBOutletCollectionType(CXCursor C) {
4576 if (C.kind != CXCursor_IBOutletCollectionAttr)
4577 return cxtype::MakeCXType(QualType(), cxcursor::getCursorASTUnit(C));
4578
4579 IBOutletCollectionAttr *A =
4580 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
4581
4582 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorASTUnit(C));
4583}
4584} // end: extern "C"
4585
4586//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00004587// CXString Operations.
4588//===----------------------------------------------------------------------===//
4589
4590extern "C" {
4591const char *clang_getCString(CXString string) {
4592 return string.Spelling;
4593}
4594
4595void clang_disposeString(CXString string) {
4596 if (string.MustFreeString && string.Spelling)
4597 free((void*)string.Spelling);
4598}
Ted Kremenek04bb7162010-01-22 22:44:15 +00004599
Ted Kremenekfb480492010-01-13 21:46:36 +00004600} // end: extern "C"
Ted Kremenek04bb7162010-01-22 22:44:15 +00004601
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004602namespace clang { namespace cxstring {
4603CXString createCXString(const char *String, bool DupString){
4604 CXString Str;
4605 if (DupString) {
4606 Str.Spelling = strdup(String);
4607 Str.MustFreeString = 1;
4608 } else {
4609 Str.Spelling = String;
4610 Str.MustFreeString = 0;
4611 }
4612 return Str;
4613}
4614
4615CXString createCXString(llvm::StringRef String, bool DupString) {
4616 CXString Result;
4617 if (DupString || (!String.empty() && String.data()[String.size()] != 0)) {
4618 char *Spelling = (char *)malloc(String.size() + 1);
4619 memmove(Spelling, String.data(), String.size());
4620 Spelling[String.size()] = 0;
4621 Result.Spelling = Spelling;
4622 Result.MustFreeString = 1;
4623 } else {
4624 Result.Spelling = String.data();
4625 Result.MustFreeString = 0;
4626 }
4627 return Result;
4628}
4629}}
4630
Ted Kremenek04bb7162010-01-22 22:44:15 +00004631//===----------------------------------------------------------------------===//
4632// Misc. utility functions.
4633//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004634
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00004635/// Default to using an 8 MB stack size on "safety" threads.
4636static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00004637
4638namespace clang {
4639
4640bool RunSafely(llvm::CrashRecoveryContext &CRC,
4641 void (*Fn)(void*), void *UserData) {
4642 if (unsigned Size = GetSafetyThreadStackSize())
4643 return CRC.RunSafelyOnThread(Fn, UserData, Size);
4644 return CRC.RunSafely(Fn, UserData);
4645}
4646
4647unsigned GetSafetyThreadStackSize() {
4648 return SafetyStackThreadSize;
4649}
4650
4651void SetSafetyThreadStackSize(unsigned Value) {
4652 SafetyStackThreadSize = Value;
4653}
4654
4655}
4656
Ted Kremenek04bb7162010-01-22 22:44:15 +00004657extern "C" {
4658
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00004659CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004660 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00004661}
4662
4663} // end: extern "C"