blob: ce02088281403eb1d32c0a8e1e628888222f1474 [file] [log] [blame]
Ted Kremenekd2fa5662009-08-26 22:36:44 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00007//
Ted Kremenekd2fa5662009-08-26 22:36:44 +00008//===----------------------------------------------------------------------===//
9//
Ted Kremenekab188932010-01-05 19:32:54 +000010// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
Ted Kremenekd2fa5662009-08-26 22:36:44 +000012//
13//===----------------------------------------------------------------------===//
14
Ted Kremenekab188932010-01-05 19:32:54 +000015#include "CIndexer.h"
Ted Kremenek16c440a2010-01-15 20:35:54 +000016#include "CXCursor.h"
Ted Kremenek0a90d322010-11-17 23:24:11 +000017#include "CXTranslationUnit.h"
Ted Kremeneked122732010-11-16 01:56:27 +000018#include "CXString.h"
Ted Kremenek95f33552010-08-26 01:42:22 +000019#include "CXType.h"
Ted Kremeneka297de22010-01-25 22:34:44 +000020#include "CXSourceLocation.h"
Douglas Gregor5352ac02010-01-28 00:27:43 +000021#include "CIndexDiagnostic.h"
Ted Kremenekab188932010-01-05 19:32:54 +000022
Ted Kremenek04bb7162010-01-22 22:44:15 +000023#include "clang/Basic/Version.h"
Douglas Gregor936ea3b2010-01-28 00:56:43 +000024
Steve Naroff50398192009-08-28 15:28:48 +000025#include "clang/AST/DeclVisitor.h"
Steve Narofffb570422009-09-22 19:25:29 +000026#include "clang/AST/StmtVisitor.h"
Douglas Gregor7d0d40e2010-01-21 16:28:34 +000027#include "clang/AST/TypeLocVisitor.h"
Benjamin Kramerb846deb2010-04-12 19:45:50 +000028#include "clang/Basic/Diagnostic.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
Douglas Gregor936ea3b2010-01-28 00:56:43 +000031#include "clang/Frontend/FrontendDiagnostic.h"
Ted Kremenekd8210652010-01-06 23:43:31 +000032#include "clang/Lex/Lexer.h"
Benjamin Kramerb846deb2010-04-12 19:45:50 +000033#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregor33e9abd2010-01-22 19:49:59 +000034#include "clang/Lex/Preprocessor.h"
Douglas Gregora67e03f2010-09-09 21:42:20 +000035#include "llvm/ADT/STLExtras.h"
Ted Kremenekd8c370c2010-11-02 23:10:24 +000036#include "llvm/ADT/Optional.h"
Douglas Gregorf5251602011-03-08 17:10:18 +000037#include "llvm/ADT/StringSwitch.h"
Ted Kremenekd8c370c2010-11-02 23:10:24 +000038#include "clang/Analysis/Support/SaveAndRestore.h"
Daniel Dunbarc7df4f32010-08-18 18:43:14 +000039#include "llvm/Support/CrashRecoveryContext.h"
Daniel Dunbar48615ff2010-10-08 19:30:33 +000040#include "llvm/Support/PrettyStackTrace.h"
Douglas Gregor02465752009-10-16 21:24:31 +000041#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor358559d2010-10-02 22:49:11 +000042#include "llvm/Support/raw_ostream.h"
Douglas Gregor7a07fcb2010-08-09 21:00:09 +000043#include "llvm/Support/Timer.h"
Michael J. Spencer03013fa2010-11-29 18:12:39 +000044#include "llvm/Support/Mutex.h"
45#include "llvm/Support/Program.h"
46#include "llvm/Support/Signals.h"
47#include "llvm/Support/Threading.h"
Ted Kremenek37f1ea02010-11-15 23:11:54 +000048#include "llvm/Support/Compiler.h"
Ted Kremenekfc062212009-10-19 21:44:57 +000049
Steve Naroff50398192009-08-28 15:28:48 +000050using namespace clang;
Ted Kremenek16c440a2010-01-15 20:35:54 +000051using namespace clang::cxcursor;
Ted Kremenekee4db4f2010-02-17 00:41:08 +000052using namespace clang::cxstring;
Steve Naroff50398192009-08-28 15:28:48 +000053
Ted Kremeneka60ed472010-11-16 08:15:36 +000054static CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) {
55 if (!TU)
56 return 0;
57 CXTranslationUnit D = new CXTranslationUnitImpl();
58 D->TUData = TU;
59 D->StringPool = createCXStringPool();
60 return D;
61}
62
Douglas Gregor33e9abd2010-01-22 19:49:59 +000063/// \brief The result of comparing two source ranges.
64enum RangeComparisonResult {
65 /// \brief Either the ranges overlap or one of the ranges is invalid.
66 RangeOverlap,
Ted Kremenekf0e23e82010-02-17 00:41:40 +000067
Douglas Gregor33e9abd2010-01-22 19:49:59 +000068 /// \brief The first range ends before the second range starts.
69 RangeBefore,
Ted Kremenekf0e23e82010-02-17 00:41:40 +000070
Douglas Gregor33e9abd2010-01-22 19:49:59 +000071 /// \brief The first range starts after the second range ends.
72 RangeAfter
73};
74
Ted Kremenekf0e23e82010-02-17 00:41:40 +000075/// \brief Compare two source ranges to determine their relative position in
Douglas Gregor33e9abd2010-01-22 19:49:59 +000076/// the translation unit.
Ted Kremenekf0e23e82010-02-17 00:41:40 +000077static RangeComparisonResult RangeCompare(SourceManager &SM,
78 SourceRange R1,
Douglas Gregor33e9abd2010-01-22 19:49:59 +000079 SourceRange R2) {
80 assert(R1.isValid() && "First range is invalid?");
81 assert(R2.isValid() && "Second range is invalid?");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000082 if (R1.getEnd() != R2.getBegin() &&
Daniel Dunbard52864b2010-02-14 10:02:57 +000083 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
Douglas Gregor33e9abd2010-01-22 19:49:59 +000084 return RangeBefore;
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000085 if (R2.getEnd() != R1.getBegin() &&
Daniel Dunbard52864b2010-02-14 10:02:57 +000086 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
Douglas Gregor33e9abd2010-01-22 19:49:59 +000087 return RangeAfter;
88 return RangeOverlap;
89}
90
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000091/// \brief Determine if a source location falls within, before, or after a
92/// a given source range.
93static RangeComparisonResult LocationCompare(SourceManager &SM,
94 SourceLocation L, SourceRange R) {
95 assert(R.isValid() && "First range is invalid?");
96 assert(L.isValid() && "Second range is invalid?");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +000097 if (L == R.getBegin() || L == R.getEnd())
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000098 return RangeOverlap;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +000099 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
100 return RangeBefore;
101 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
102 return RangeAfter;
103 return RangeOverlap;
104}
105
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000106/// \brief Translate a Clang source range into a CIndex source range.
107///
108/// Clang internally represents ranges where the end location points to the
109/// start of the token at the end. However, for external clients it is more
110/// useful to have a CXSourceRange be a proper half-open interval. This routine
111/// does the appropriate translation.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000112CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000113 const LangOptions &LangOpts,
Chris Lattner0a76aae2010-06-18 22:45:06 +0000114 const CharSourceRange &R) {
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000115 // We want the last character in this location, so we will adjust the
Douglas Gregor6a5a23f2010-03-19 21:51:54 +0000116 // location accordingly.
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000117 SourceLocation EndLoc = R.getEnd();
Douglas Gregora9b06d42010-11-09 06:24:54 +0000118 if (EndLoc.isValid() && EndLoc.isMacroID())
119 EndLoc = SM.getSpellingLoc(EndLoc);
Chris Lattner0a76aae2010-06-18 22:45:06 +0000120 if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
Douglas Gregor6a5a23f2010-03-19 21:51:54 +0000121 unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
Daniel Dunbar76dd3c22010-02-14 01:47:29 +0000122 EndLoc = EndLoc.getFileLocWithOffset(Length);
123 }
124
125 CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
126 R.getBegin().getRawEncoding(),
127 EndLoc.getRawEncoding() };
128 return Result;
129}
Douglas Gregor1db19de2010-01-19 21:36:55 +0000130
Ted Kremenek8a8da7d2010-01-06 03:42:32 +0000131//===----------------------------------------------------------------------===//
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000132// Cursor visitor.
Ted Kremenek8a8da7d2010-01-06 03:42:32 +0000133//===----------------------------------------------------------------------===//
134
Steve Naroff89922f82009-08-31 00:59:03 +0000135namespace {
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000136
137class VisitorJob {
138public:
Ted Kremenekcdb4caf2010-11-12 21:34:12 +0000139 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
Ted Kremeneke4979cc2010-11-13 00:58:18 +0000140 TypeLocVisitKind, OverloadExprPartsKind,
Ted Kremenek60608ec2010-11-17 00:50:47 +0000141 DeclRefExprPartsKind, LabelRefVisitKind,
Ted Kremenekf64d8032010-11-18 00:02:32 +0000142 ExplicitTemplateArgsVisitKind,
143 NestedNameSpecifierVisitKind,
Douglas Gregorf3db29f2011-02-25 18:19:59 +0000144 NestedNameSpecifierLocVisitKind,
Ted Kremenekcdba6592010-11-18 00:42:18 +0000145 DeclarationNameInfoVisitKind,
Douglas Gregor94d96292011-01-19 20:34:17 +0000146 MemberRefVisitKind, SizeOfPackExprPartsKind };
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000147protected:
Ted Kremenekf64d8032010-11-18 00:02:32 +0000148 void *data[3];
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000149 CXCursor parent;
150 Kind K;
Ted Kremenekf64d8032010-11-18 00:02:32 +0000151 VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
152 : parent(C), K(k) {
153 data[0] = d1;
154 data[1] = d2;
155 data[2] = d3;
156 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000157public:
158 Kind getKind() const { return K; }
159 const CXCursor &getParent() const { return parent; }
160 static bool classof(VisitorJob *VJ) { return true; }
161};
162
163typedef llvm::SmallVector<VisitorJob, 10> VisitorWorkList;
164
Douglas Gregorb1373d02010-01-20 20:59:29 +0000165// Cursor visitor.
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000166class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
Ted Kremenekcdba6592010-11-18 00:42:18 +0000167 public TypeLocVisitor<CursorVisitor, bool>
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000168{
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000169 /// \brief The translation unit we are traversing.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000170 CXTranslationUnit TU;
171 ASTUnit *AU;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000172
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000173 /// \brief The parent cursor whose children we are traversing.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000174 CXCursor Parent;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000175
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000176 /// \brief The declaration that serves at the parent of any statement or
177 /// expression nodes.
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000178 Decl *StmtParent;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000179
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000180 /// \brief The visitor function.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000181 CXCursorVisitor Visitor;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000182
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000183 /// \brief The opaque client data, to be passed along to the visitor.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000184 CXClientData ClientData;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000185
Douglas Gregor7d1d49d2009-10-16 20:01:17 +0000186 // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
187 // to the visitor. Declarations with a PCH level greater than this value will
188 // be suppressed.
189 unsigned MaxPCHLevel;
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000190
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000191 /// \brief Whether we should visit the preprocessing record entries last,
192 /// after visiting other declarations.
193 bool VisitPreprocessorLast;
194
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000195 /// \brief When valid, a source range to which the cursor should restrict
196 /// its search.
197 SourceRange RegionOfInterest;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000198
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000199 // FIXME: Eventually remove. This part of a hack to support proper
200 // iteration over all Decls contained lexically within an ObjC container.
201 DeclContext::decl_iterator *DI_current;
202 DeclContext::decl_iterator DE_current;
203
Ted Kremenekd1ded662010-11-15 23:31:32 +0000204 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
205 llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
206 llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
207
Douglas Gregorb1373d02010-01-20 20:59:29 +0000208 using DeclVisitor<CursorVisitor, bool>::Visit;
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000209 using TypeLocVisitor<CursorVisitor, bool>::Visit;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000210
211 /// \brief Determine whether this particular source range comes before, comes
212 /// after, or overlaps the region of interest.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000213 ///
Daniel Dunbard52864b2010-02-14 10:02:57 +0000214 /// \param R a half-open source range retrieved from the abstract syntax tree.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000215 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
216
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000217 class SetParentRAII {
218 CXCursor &Parent;
219 Decl *&StmtParent;
220 CXCursor OldParent;
221
222 public:
223 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
224 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
225 {
226 Parent = NewParent;
227 if (clang_isDeclaration(Parent.kind))
228 StmtParent = getCursorDecl(Parent);
229 }
230
231 ~SetParentRAII() {
232 Parent = OldParent;
233 if (clang_isDeclaration(Parent.kind))
234 StmtParent = getCursorDecl(Parent);
235 }
236 };
237
Steve Naroff89922f82009-08-31 00:59:03 +0000238public:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000239 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
240 CXClientData ClientData,
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000241 unsigned MaxPCHLevel,
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000242 bool VisitPreprocessorLast,
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000243 SourceRange RegionOfInterest = SourceRange())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000244 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
245 Visitor(Visitor), ClientData(ClientData),
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000246 MaxPCHLevel(MaxPCHLevel), VisitPreprocessorLast(VisitPreprocessorLast),
247 RegionOfInterest(RegionOfInterest), DI_current(0)
Douglas Gregorb1373d02010-01-20 20:59:29 +0000248 {
249 Parent.kind = CXCursor_NoDeclFound;
250 Parent.data[0] = 0;
251 Parent.data[1] = 0;
252 Parent.data[2] = 0;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000253 StmtParent = 0;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000254 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000255
Ted Kremenekd1ded662010-11-15 23:31:32 +0000256 ~CursorVisitor() {
257 // Free the pre-allocated worklists for data-recursion.
258 for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
259 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
260 delete *I;
261 }
262 }
263
Ted Kremeneka60ed472010-11-16 08:15:36 +0000264 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
265 CXTranslationUnit getTU() const { return TU; }
Ted Kremenekab979612010-11-11 08:05:23 +0000266
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000267 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000268
269 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
270 getPreprocessedEntities();
271
Douglas Gregorb1373d02010-01-20 20:59:29 +0000272 bool VisitChildren(CXCursor Parent);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000273
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000274 // Declaration visitors
Richard Smith162e1c12011-04-15 14:24:37 +0000275 bool VisitTypeAliasDecl(TypeAliasDecl *D);
Ted Kremenek09dfa372010-02-18 05:46:33 +0000276 bool VisitAttributes(Decl *D);
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000277 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenek3064ef92010-08-27 21:34:58 +0000278 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000279 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000280 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000281 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
282 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000283 bool VisitTagDecl(TagDecl *D);
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000284 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregor74dbe642010-08-31 19:31:58 +0000285 bool VisitClassTemplatePartialSpecializationDecl(
286 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000287 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000288 bool VisitEnumConstantDecl(EnumConstantDecl *D);
289 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
290 bool VisitFunctionDecl(FunctionDecl *ND);
291 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000292 bool VisitVarDecl(VarDecl *);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000293 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000294 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor39d6f072010-08-31 19:02:00 +0000295 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000296 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000297 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
298 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
299 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
300 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek23173d72010-05-18 21:09:07 +0000301 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremenek79758f62010-02-18 22:36:18 +0000302 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
303 bool VisitObjCImplDecl(ObjCImplDecl *D);
304 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
305 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000306 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
307 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
308 bool VisitObjCClassDecl(ObjCClassDecl *D);
Douglas Gregora4ffd852010-11-17 01:03:52 +0000309 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
Ted Kremeneka0536d82010-05-07 01:04:29 +0000310 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenek8f06e0e2010-05-06 23:38:21 +0000311 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregor69319002010-08-31 23:48:11 +0000312 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000313 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregor7e242562010-09-01 19:52:22 +0000314 bool VisitUsingDecl(UsingDecl *D);
315 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
316 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000317
Douglas Gregor01829d32010-08-31 14:41:23 +0000318 // Name visitor
319 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000320 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregordc355712011-02-25 00:36:19 +0000321 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
Douglas Gregor01829d32010-08-31 14:41:23 +0000322
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000323 // Template visitors
324 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregor0b36e612010-08-31 20:37:03 +0000325 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000326 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
327
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000328 // Type visitors
Douglas Gregor01829d32010-08-31 14:41:23 +0000329 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000330 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000331 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000332 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
333 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000334 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000335 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCallc12c5bb2010-05-15 11:32:37 +0000336 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000337 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
Abramo Bagnara075f8f12010-12-10 16:29:40 +0000338 bool VisitParenTypeLoc(ParenTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000339 bool VisitPointerTypeLoc(PointerTypeLoc TL);
340 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
341 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
342 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
343 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor01829d32010-08-31 14:41:23 +0000344 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000345 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000346 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000347 // FIXME: Implement visitors here when the unimplemented TypeLocs get
348 // implemented
349 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
Douglas Gregor7536dd52010-12-20 02:24:11 +0000350 bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000351 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000352 bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
Douglas Gregor94fdffa2011-03-01 20:11:18 +0000353 bool VisitDependentTemplateSpecializationTypeLoc(
354 DependentTemplateSpecializationTypeLoc TL);
Douglas Gregor9e876872011-03-01 18:12:44 +0000355 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000356
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000357 // Data-recursive visitor functions.
358 bool IsInRegionOfInterest(CXCursor C);
359 bool RunVisitorWorkList(VisitorWorkList &WL);
360 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
Ted Kremenekcdba6592010-11-18 00:42:18 +0000361 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
Steve Naroff89922f82009-08-31 00:59:03 +0000362};
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000363
Ted Kremenekab188932010-01-05 19:32:54 +0000364} // end anonymous namespace
Benjamin Kramer5e4bc592009-10-18 16:11:04 +0000365
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000366static SourceRange getRawCursorExtent(CXCursor C);
Douglas Gregor66537982010-11-17 17:14:07 +0000367static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
368
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000369
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000370RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000371 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000372}
373
Douglas Gregorb1373d02010-01-20 20:59:29 +0000374/// \brief Visit the given cursor and, if requested by the visitor,
375/// its children.
376///
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000377/// \param Cursor the cursor to visit.
378///
379/// \param CheckRegionOfInterest if true, then the caller already checked that
380/// this cursor is within the region of interest.
381///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000382/// \returns true if the visitation should be aborted, false if it
383/// should continue.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000384bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregorb1373d02010-01-20 20:59:29 +0000385 if (clang_isInvalid(Cursor.kind))
386 return false;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000387
Douglas Gregorb1373d02010-01-20 20:59:29 +0000388 if (clang_isDeclaration(Cursor.kind)) {
389 Decl *D = getCursorDecl(Cursor);
390 assert(D && "Invalid declaration cursor");
391 if (D->getPCHLevel() > MaxPCHLevel)
392 return false;
393
394 if (D->isImplicit())
395 return false;
396 }
397
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000398 // If we have a range of interest, and this cursor doesn't intersect with it,
399 // we're done.
400 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000401 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbarf408f322010-02-14 08:32:05 +0000402 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000403 return false;
404 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000405
Douglas Gregorb1373d02010-01-20 20:59:29 +0000406 switch (Visitor(Cursor, Parent, ClientData)) {
407 case CXChildVisit_Break:
408 return true;
409
410 case CXChildVisit_Continue:
411 return false;
412
413 case CXChildVisit_Recurse:
414 return VisitChildren(Cursor);
415 }
416
Douglas Gregorfd643772010-01-25 16:45:46 +0000417 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000418}
419
Douglas Gregor788f5a12010-03-20 00:41:21 +0000420std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
421CursorVisitor::getPreprocessedEntities() {
422 PreprocessingRecord &PPRec
Ted Kremeneka60ed472010-11-16 08:15:36 +0000423 = *AU->getPreprocessor().getPreprocessingRecord();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000424
425 bool OnlyLocalDecls
Douglas Gregor32038bb2010-12-21 19:07:48 +0000426 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
427
428 if (OnlyLocalDecls && RegionOfInterest.isValid()) {
429 // If we would only look at local declarations but we have a region of
430 // interest, check whether that region of interest is in the main file.
431 // If not, we should traverse all declarations.
432 // FIXME: My kingdom for a proper binary search approach to finding
433 // cursors!
434 std::pair<FileID, unsigned> Location
435 = AU->getSourceManager().getDecomposedInstantiationLoc(
436 RegionOfInterest.getBegin());
437 if (Location.first != AU->getSourceManager().getMainFileID())
438 OnlyLocalDecls = false;
439 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000440
Douglas Gregor89d99802010-11-30 06:16:57 +0000441 PreprocessingRecord::iterator StartEntity, EndEntity;
442 if (OnlyLocalDecls) {
443 StartEntity = AU->pp_entity_begin();
444 EndEntity = AU->pp_entity_end();
445 } else {
446 StartEntity = PPRec.begin();
447 EndEntity = PPRec.end();
448 }
449
Douglas Gregor788f5a12010-03-20 00:41:21 +0000450 // There is no region of interest; we have to walk everything.
451 if (RegionOfInterest.isInvalid())
Douglas Gregor89d99802010-11-30 06:16:57 +0000452 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000453
454 // Find the file in which the region of interest lands.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000455 SourceManager &SM = AU->getSourceManager();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000456 std::pair<FileID, unsigned> Begin
457 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
458 std::pair<FileID, unsigned> End
459 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
460
461 // The region of interest spans files; we have to walk everything.
462 if (Begin.first != End.first)
Douglas Gregor89d99802010-11-30 06:16:57 +0000463 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000464
465 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
Ted Kremeneka60ed472010-11-16 08:15:36 +0000466 = AU->getPreprocessedEntitiesByFile();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000467 if (ByFileMap.empty()) {
468 // Build the mapping from files to sets of preprocessed entities.
Douglas Gregor89d99802010-11-30 06:16:57 +0000469 for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
Douglas Gregor788f5a12010-03-20 00:41:21 +0000470 std::pair<FileID, unsigned> P
471 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
Douglas Gregor89d99802010-11-30 06:16:57 +0000472
Douglas Gregor788f5a12010-03-20 00:41:21 +0000473 ByFileMap[P.first].push_back(*E);
474 }
475 }
476
477 return std::make_pair(ByFileMap[Begin.first].begin(),
478 ByFileMap[Begin.first].end());
479}
480
Douglas Gregorb1373d02010-01-20 20:59:29 +0000481/// \brief Visit the children of the given cursor.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000482///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000483/// \returns true if the visitation should be aborted, false if it
484/// should continue.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000485bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregorc314aa42011-03-02 19:17:03 +0000486 if (clang_isReference(Cursor.kind) &&
487 Cursor.kind != CXCursor_CXXBaseSpecifier) {
Douglas Gregora59e3902010-01-21 23:27:09 +0000488 // By definition, references have no children.
489 return false;
490 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000491
492 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregorb1373d02010-01-20 20:59:29 +0000493 // done.
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000494 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000495
Douglas Gregorb1373d02010-01-20 20:59:29 +0000496 if (clang_isDeclaration(Cursor.kind)) {
497 Decl *D = getCursorDecl(Cursor);
Douglas Gregor06d9b1a2011-04-14 21:41:34 +0000498 if (!D)
499 return false;
500
Ted Kremenek539311e2010-02-18 18:47:01 +0000501 return VisitAttributes(D) || Visit(D);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000502 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000503
Douglas Gregor06d9b1a2011-04-14 21:41:34 +0000504 if (clang_isStatement(Cursor.kind)) {
505 if (Stmt *S = getCursorStmt(Cursor))
506 return Visit(S);
507
508 return false;
509 }
510
511 if (clang_isExpression(Cursor.kind)) {
512 if (Expr *E = getCursorExpr(Cursor))
513 return Visit(E);
514
515 return false;
516 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000517
Douglas Gregorb1373d02010-01-20 20:59:29 +0000518 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000519 CXTranslationUnit tu = getCursorTU(Cursor);
520 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000521
522 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
523 for (unsigned I = 0; I != 2; ++I) {
524 if (VisitOrder[I]) {
525 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
526 RegionOfInterest.isInvalid()) {
527 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
528 TLEnd = CXXUnit->top_level_end();
529 TL != TLEnd; ++TL) {
530 if (Visit(MakeCXCursor(*TL, tu), true))
531 return true;
532 }
533 } else if (VisitDeclContext(
534 CXXUnit->getASTContext().getTranslationUnitDecl()))
Douglas Gregor7b691f332010-01-20 21:13:59 +0000535 return true;
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000536 continue;
Douglas Gregor7b691f332010-01-20 21:13:59 +0000537 }
Bob Wilson3178cb62010-03-19 03:57:57 +0000538
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000539 // Walk the preprocessing record.
540 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
541 // FIXME: Once we have the ability to deserialize a preprocessing record,
542 // do so.
543 PreprocessingRecord::iterator E, EEnd;
544 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
545 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
546 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
547 return true;
548
549 continue;
550 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000551
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000552 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
553 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
554 return true;
555
556 continue;
557 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000558
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000559 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
560 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
561 return true;
562
563 continue;
564 }
Douglas Gregorecdcb882010-10-20 22:00:55 +0000565 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000566 }
567 }
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000568
Douglas Gregor7b691f332010-01-20 21:13:59 +0000569 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000570 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000571
Douglas Gregorc314aa42011-03-02 19:17:03 +0000572 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
573 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
574 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
575 return Visit(BaseTSInfo->getTypeLoc());
576 }
577 }
578 }
579
Douglas Gregorb1373d02010-01-20 20:59:29 +0000580 // Nothing to visit at the moment.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000581 return false;
582}
583
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000584bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
John McCallfc929202010-06-04 22:33:30 +0000585 if (Visit(B->getSignatureAsWritten()->getTypeLoc()))
586 return true;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000587
Ted Kremenek664cffd2010-07-22 11:30:19 +0000588 if (Stmt *Body = B->getBody())
589 return Visit(MakeCXCursor(Body, StmtParent, TU));
590
591 return false;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000592}
593
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000594llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
595 if (RegionOfInterest.isValid()) {
Douglas Gregor66537982010-11-17 17:14:07 +0000596 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000597 if (Range.isInvalid())
598 return llvm::Optional<bool>();
Douglas Gregor66537982010-11-17 17:14:07 +0000599
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000600 switch (CompareRegionOfInterest(Range)) {
601 case RangeBefore:
602 // This declaration comes before the region of interest; skip it.
603 return llvm::Optional<bool>();
604
605 case RangeAfter:
606 // This declaration comes after the region of interest; we're done.
607 return false;
608
609 case RangeOverlap:
610 // This declaration overlaps the region of interest; visit it.
611 break;
612 }
613 }
614 return true;
615}
616
617bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
618 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
619
620 // FIXME: Eventually remove. This part of a hack to support proper
621 // iteration over all Decls contained lexically within an ObjC container.
622 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
623 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
624
625 for ( ; I != E; ++I) {
Ted Kremenek23173d72010-05-18 21:09:07 +0000626 Decl *D = *I;
627 if (D->getLexicalDeclContext() != DC)
628 continue;
Ted Kremenek23173d72010-05-18 21:09:07 +0000629 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000630 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
631 if (!V.hasValue())
632 continue;
633 if (!V.getValue())
634 return false;
Daniel Dunbard52864b2010-02-14 10:02:57 +0000635 if (Visit(Cursor, true))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000636 return true;
637 }
Douglas Gregorb1373d02010-01-20 20:59:29 +0000638 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000639}
640
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000641bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
642 llvm_unreachable("Translation units are visited directly by Visit()");
643 return false;
644}
645
Richard Smith162e1c12011-04-15 14:24:37 +0000646bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
647 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
648 return Visit(TSInfo->getTypeLoc());
649
650 return false;
651}
652
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000653bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
654 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
655 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000656
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000657 return false;
658}
659
660bool CursorVisitor::VisitTagDecl(TagDecl *D) {
661 return VisitDeclContext(D);
662}
663
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000664bool CursorVisitor::VisitClassTemplateSpecializationDecl(
665 ClassTemplateSpecializationDecl *D) {
666 bool ShouldVisitBody = false;
667 switch (D->getSpecializationKind()) {
668 case TSK_Undeclared:
669 case TSK_ImplicitInstantiation:
670 // Nothing to visit
671 return false;
672
673 case TSK_ExplicitInstantiationDeclaration:
674 case TSK_ExplicitInstantiationDefinition:
675 break;
676
677 case TSK_ExplicitSpecialization:
678 ShouldVisitBody = true;
679 break;
680 }
681
682 // Visit the template arguments used in the specialization.
683 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
684 TypeLoc TL = SpecType->getTypeLoc();
685 if (TemplateSpecializationTypeLoc *TSTLoc
686 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
687 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
688 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
689 return true;
690 }
691 }
692
693 if (ShouldVisitBody && VisitCXXRecordDecl(D))
694 return true;
695
696 return false;
697}
698
Douglas Gregor74dbe642010-08-31 19:31:58 +0000699bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
700 ClassTemplatePartialSpecializationDecl *D) {
701 // FIXME: Visit the "outer" template parameter lists on the TagDecl
702 // before visiting these template parameters.
703 if (VisitTemplateParameters(D->getTemplateParameters()))
704 return true;
705
706 // Visit the partial specialization arguments.
707 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
708 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
710 return true;
711
712 return VisitCXXRecordDecl(D);
713}
714
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000715bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor84b51d72010-09-01 20:16:53 +0000716 // Visit the default argument.
717 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
718 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
719 if (Visit(DefArg->getTypeLoc()))
720 return true;
721
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000722 return false;
723}
724
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000725bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
726 if (Expr *Init = D->getInitExpr())
727 return Visit(MakeCXCursor(Init, StmtParent, TU));
728 return false;
729}
730
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000731bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
732 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
733 if (Visit(TSInfo->getTypeLoc()))
734 return true;
735
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000736 // Visit the nested-name-specifier, if present.
737 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
738 if (VisitNestedNameSpecifierLoc(QualifierLoc))
739 return true;
740
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000741 return false;
742}
743
Douglas Gregora67e03f2010-09-09 21:42:20 +0000744/// \brief Compare two base or member initializers based on their source order.
Sean Huntcbb67482011-01-08 20:30:50 +0000745static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
746 CXXCtorInitializer const * const *X
747 = static_cast<CXXCtorInitializer const * const *>(Xp);
748 CXXCtorInitializer const * const *Y
749 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000750
751 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
752 return -1;
753 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
754 return 1;
755 else
756 return 0;
757}
758
Douglas Gregorb1373d02010-01-20 20:59:29 +0000759bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor01829d32010-08-31 14:41:23 +0000760 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
761 // Visit the function declaration's syntactic components in the order
762 // written. This requires a bit of work.
Abramo Bagnara723df242010-12-14 22:11:44 +0000763 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor01829d32010-08-31 14:41:23 +0000764 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
765
766 // If we have a function declared directly (without the use of a typedef),
767 // visit just the return type. Otherwise, just visit the function's type
768 // now.
769 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
770 (!FTL && Visit(TL)))
771 return true;
772
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000773 // Visit the nested-name-specifier, if present.
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000774 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
775 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000776 return true;
Douglas Gregor01829d32010-08-31 14:41:23 +0000777
778 // Visit the declaration name.
779 if (VisitDeclarationNameInfo(ND->getNameInfo()))
780 return true;
781
782 // FIXME: Visit explicitly-specified template arguments!
783
784 // Visit the function parameters, if we have a function type.
785 if (FTL && VisitFunctionTypeLoc(*FTL, true))
786 return true;
787
788 // FIXME: Attributes?
789 }
790
Douglas Gregora67e03f2010-09-09 21:42:20 +0000791 if (ND->isThisDeclarationADefinition()) {
792 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
793 // Find the initializers that were written in the source.
Sean Huntcbb67482011-01-08 20:30:50 +0000794 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregora67e03f2010-09-09 21:42:20 +0000795 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
796 IEnd = Constructor->init_end();
797 I != IEnd; ++I) {
798 if (!(*I)->isWritten())
799 continue;
800
801 WrittenInits.push_back(*I);
802 }
803
804 // Sort the initializers in source order
805 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Sean Huntcbb67482011-01-08 20:30:50 +0000806 &CompareCXXCtorInitializers);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000807
808 // Visit the initializers in source order
809 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Sean Huntcbb67482011-01-08 20:30:50 +0000810 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichet00eb3f92010-12-04 09:14:42 +0000811 if (Init->isAnyMemberInitializer()) {
812 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregora67e03f2010-09-09 21:42:20 +0000813 Init->getMemberLocation(), TU)))
814 return true;
815 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
816 if (Visit(BaseInfo->getTypeLoc()))
817 return true;
818 }
819
820 // Visit the initializer value.
821 if (Expr *Initializer = Init->getInit())
822 if (Visit(MakeCXCursor(Initializer, ND, TU)))
823 return true;
824 }
825 }
826
827 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
828 return true;
829 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000830
Douglas Gregorb1373d02010-01-20 20:59:29 +0000831 return false;
832}
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000833
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000834bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
835 if (VisitDeclaratorDecl(D))
836 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000837
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000838 if (Expr *BitWidth = D->getBitWidth())
839 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000840
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000841 return false;
842}
843
844bool CursorVisitor::VisitVarDecl(VarDecl *D) {
845 if (VisitDeclaratorDecl(D))
846 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000847
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000848 if (Expr *Init = D->getInit())
849 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000850
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000851 return false;
852}
853
Douglas Gregor84b51d72010-09-01 20:16:53 +0000854bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
855 if (VisitDeclaratorDecl(D))
856 return true;
857
858 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
859 if (Expr *DefArg = D->getDefaultArgument())
860 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
861
862 return false;
863}
864
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000865bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
866 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
867 // before visiting these template parameters.
868 if (VisitTemplateParameters(D->getTemplateParameters()))
869 return true;
870
871 return VisitFunctionDecl(D->getTemplatedDecl());
872}
873
Douglas Gregor39d6f072010-08-31 19:02:00 +0000874bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
875 // FIXME: Visit the "outer" template parameter lists on the TagDecl
876 // before visiting these template parameters.
877 if (VisitTemplateParameters(D->getTemplateParameters()))
878 return true;
879
880 return VisitCXXRecordDecl(D->getTemplatedDecl());
881}
882
Douglas Gregor84b51d72010-09-01 20:16:53 +0000883bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
884 if (VisitTemplateParameters(D->getTemplateParameters()))
885 return true;
886
887 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
888 VisitTemplateArgumentLoc(D->getDefaultArgument()))
889 return true;
890
891 return false;
892}
893
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000894bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor4bc1cb62010-03-08 14:59:44 +0000895 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
896 if (Visit(TSInfo->getTypeLoc()))
897 return true;
898
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000899 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000900 PEnd = ND->param_end();
901 P != PEnd; ++P) {
902 if (Visit(MakeCXCursor(*P, TU)))
903 return true;
904 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000905
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000906 if (ND->isThisDeclarationADefinition() &&
907 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
908 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000909
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000910 return false;
911}
912
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000913namespace {
914 struct ContainerDeclsSort {
915 SourceManager &SM;
916 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
917 bool operator()(Decl *A, Decl *B) {
918 SourceLocation L_A = A->getLocStart();
919 SourceLocation L_B = B->getLocStart();
920 assert(L_A.isValid() && L_B.isValid());
921 return SM.isBeforeInTranslationUnit(L_A, L_B);
922 }
923 };
924}
925
Douglas Gregora59e3902010-01-21 23:27:09 +0000926bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000927 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
928 // an @implementation can lexically contain Decls that are not properly
929 // nested in the AST. When we identify such cases, we need to retrofit
930 // this nesting here.
931 if (!DI_current)
932 return VisitDeclContext(D);
933
934 // Scan the Decls that immediately come after the container
935 // in the current DeclContext. If any fall within the
936 // container's lexical region, stash them into a vector
937 // for later processing.
938 llvm::SmallVector<Decl *, 24> DeclsInContainer;
939 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000940 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000941 if (EndLoc.isValid()) {
942 DeclContext::decl_iterator next = *DI_current;
943 while (++next != DE_current) {
944 Decl *D_next = *next;
945 if (!D_next)
946 break;
947 SourceLocation L = D_next->getLocStart();
948 if (!L.isValid())
949 break;
950 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
951 *DI_current = next;
952 DeclsInContainer.push_back(D_next);
953 continue;
954 }
955 break;
956 }
957 }
958
959 // The common case.
960 if (DeclsInContainer.empty())
961 return VisitDeclContext(D);
962
963 // Get all the Decls in the DeclContext, and sort them with the
964 // additional ones we've collected. Then visit them.
965 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
966 I!=E; ++I) {
967 Decl *subDecl = *I;
Ted Kremenek0582c892010-11-02 23:17:51 +0000968 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
969 subDecl->getLocStart().isInvalid())
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000970 continue;
971 DeclsInContainer.push_back(subDecl);
972 }
973
974 // Now sort the Decls so that they appear in lexical order.
975 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
976 ContainerDeclsSort(SM));
977
978 // Now visit the decls.
979 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
980 E = DeclsInContainer.end(); I != E; ++I) {
981 CXCursor Cursor = MakeCXCursor(*I, TU);
982 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
983 if (!V.hasValue())
984 continue;
985 if (!V.getValue())
986 return false;
987 if (Visit(Cursor, true))
988 return true;
989 }
990 return false;
Douglas Gregora59e3902010-01-21 23:27:09 +0000991}
992
Douglas Gregorb1373d02010-01-20 20:59:29 +0000993bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000994 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
995 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000996 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000997
Douglas Gregor78db0cd2010-01-16 15:44:18 +0000998 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
999 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1000 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001001 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001002 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001003
Douglas Gregora59e3902010-01-21 23:27:09 +00001004 return VisitObjCContainerDecl(ND);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001005}
1006
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001007bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1008 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1009 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1010 E = PID->protocol_end(); I != E; ++I, ++PL)
1011 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1012 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001013
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001014 return VisitObjCContainerDecl(PID);
1015}
1016
Ted Kremenek23173d72010-05-18 21:09:07 +00001017bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor83cb9422010-09-09 17:09:21 +00001018 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCallfc929202010-06-04 22:33:30 +00001019 return true;
1020
Ted Kremenek23173d72010-05-18 21:09:07 +00001021 // FIXME: This implements a workaround with @property declarations also being
1022 // installed in the DeclContext for the @interface. Eventually this code
1023 // should be removed.
1024 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1025 if (!CDecl || !CDecl->IsClassExtension())
1026 return false;
1027
1028 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1029 if (!ID)
1030 return false;
1031
1032 IdentifierInfo *PropertyId = PD->getIdentifier();
1033 ObjCPropertyDecl *prevDecl =
1034 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1035
1036 if (!prevDecl)
1037 return false;
1038
1039 // Visit synthesized methods since they will be skipped when visiting
1040 // the @interface.
1041 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001042 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001043 if (Visit(MakeCXCursor(MD, TU)))
1044 return true;
1045
1046 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001047 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001048 if (Visit(MakeCXCursor(MD, TU)))
1049 return true;
1050
1051 return false;
1052}
1053
Douglas Gregorb1373d02010-01-20 20:59:29 +00001054bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001055 // Issue callbacks for super class.
Douglas Gregorb1373d02010-01-20 20:59:29 +00001056 if (D->getSuperClass() &&
1057 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001058 D->getSuperClassLoc(),
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001059 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001060 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001061
Douglas Gregor78db0cd2010-01-16 15:44:18 +00001062 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1063 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1064 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001065 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001066 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001067
Douglas Gregora59e3902010-01-21 23:27:09 +00001068 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001069}
1070
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001071bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1072 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001073}
1074
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001075bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremenekebfa3392010-03-19 20:39:03 +00001076 // 'ID' could be null when dealing with invalid code.
1077 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1078 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1079 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001080
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001081 return VisitObjCImplDecl(D);
1082}
1083
1084bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1085#if 0
1086 // Issue callbacks for super class.
1087 // FIXME: No source location information!
1088 if (D->getSuperClass() &&
1089 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001090 D->getSuperClassLoc(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001091 TU)))
1092 return true;
1093#endif
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001094
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001095 return VisitObjCImplDecl(D);
1096}
1097
1098bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1099 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1100 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1101 E = D->protocol_end();
1102 I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001103 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001104 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001105
1106 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001107}
1108
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001109bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1110 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1111 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1112 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001113
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001114 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001115}
1116
Douglas Gregora4ffd852010-11-17 01:03:52 +00001117bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1118 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1119 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1120
1121 return false;
1122}
1123
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00001124bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1125 return VisitDeclContext(D);
1126}
1127
Douglas Gregor69319002010-08-31 23:48:11 +00001128bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001129 // Visit nested-name-specifier.
Douglas Gregor0cfaf6a2011-02-25 17:08:07 +00001130 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1131 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001132 return true;
Douglas Gregor69319002010-08-31 23:48:11 +00001133
1134 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1135 D->getTargetNameLoc(), TU));
1136}
1137
Douglas Gregor7e242562010-09-01 19:52:22 +00001138bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001139 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001140 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1141 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001142 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001143 }
Douglas Gregor7e242562010-09-01 19:52:22 +00001144
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001145 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1146 return true;
1147
Douglas Gregor7e242562010-09-01 19:52:22 +00001148 return VisitDeclarationNameInfo(D->getNameInfo());
1149}
1150
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001151bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001152 // Visit nested-name-specifier.
Douglas Gregordb992412011-02-25 16:33:46 +00001153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001155 return true;
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001156
1157 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1158 D->getIdentLocation(), TU));
1159}
1160
Douglas Gregor7e242562010-09-01 19:52:22 +00001161bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001162 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001163 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1164 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001165 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001166 }
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001167
Douglas Gregor7e242562010-09-01 19:52:22 +00001168 return VisitDeclarationNameInfo(D->getNameInfo());
1169}
1170
1171bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1172 UnresolvedUsingTypenameDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001173 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001174 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1175 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001176 return true;
1177
Douglas Gregor7e242562010-09-01 19:52:22 +00001178 return false;
1179}
1180
Douglas Gregor01829d32010-08-31 14:41:23 +00001181bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1182 switch (Name.getName().getNameKind()) {
1183 case clang::DeclarationName::Identifier:
1184 case clang::DeclarationName::CXXLiteralOperatorName:
1185 case clang::DeclarationName::CXXOperatorName:
1186 case clang::DeclarationName::CXXUsingDirective:
1187 return false;
1188
1189 case clang::DeclarationName::CXXConstructorName:
1190 case clang::DeclarationName::CXXDestructorName:
1191 case clang::DeclarationName::CXXConversionFunctionName:
1192 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1193 return Visit(TSInfo->getTypeLoc());
1194 return false;
1195
1196 case clang::DeclarationName::ObjCZeroArgSelector:
1197 case clang::DeclarationName::ObjCOneArgSelector:
1198 case clang::DeclarationName::ObjCMultiArgSelector:
1199 // FIXME: Per-identifier location info?
1200 return false;
1201 }
1202
1203 return false;
1204}
1205
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001206bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1207 SourceRange Range) {
1208 // FIXME: This whole routine is a hack to work around the lack of proper
1209 // source information in nested-name-specifiers (PR5791). Since we do have
1210 // a beginning source location, we can visit the first component of the
1211 // nested-name-specifier, if it's a single-token component.
1212 if (!NNS)
1213 return false;
1214
1215 // Get the first component in the nested-name-specifier.
1216 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1217 NNS = Prefix;
1218
1219 switch (NNS->getKind()) {
1220 case NestedNameSpecifier::Namespace:
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001221 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1222 TU));
1223
Douglas Gregor14aba762011-02-24 02:36:08 +00001224 case NestedNameSpecifier::NamespaceAlias:
1225 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1226 Range.getBegin(), TU));
1227
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001228 case NestedNameSpecifier::TypeSpec: {
1229 // If the type has a form where we know that the beginning of the source
1230 // range matches up with a reference cursor. Visit the appropriate reference
1231 // cursor.
John McCallf4c73712011-01-19 06:33:43 +00001232 const Type *T = NNS->getAsType();
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001233 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1234 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1235 if (const TagType *Tag = dyn_cast<TagType>(T))
1236 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1237 if (const TemplateSpecializationType *TST
1238 = dyn_cast<TemplateSpecializationType>(T))
1239 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1240 break;
1241 }
1242
1243 case NestedNameSpecifier::TypeSpecWithTemplate:
1244 case NestedNameSpecifier::Global:
1245 case NestedNameSpecifier::Identifier:
1246 break;
1247 }
1248
1249 return false;
1250}
1251
Douglas Gregordc355712011-02-25 00:36:19 +00001252bool
1253CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1254 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1255 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1256 Qualifiers.push_back(Qualifier);
1257
1258 while (!Qualifiers.empty()) {
1259 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1260 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1261 switch (NNS->getKind()) {
1262 case NestedNameSpecifier::Namespace:
1263 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001264 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001265 TU)))
1266 return true;
1267
1268 break;
1269
1270 case NestedNameSpecifier::NamespaceAlias:
1271 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001272 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001273 TU)))
1274 return true;
1275
1276 break;
1277
1278 case NestedNameSpecifier::TypeSpec:
1279 case NestedNameSpecifier::TypeSpecWithTemplate:
1280 if (Visit(Q.getTypeLoc()))
1281 return true;
1282
1283 break;
1284
1285 case NestedNameSpecifier::Global:
1286 case NestedNameSpecifier::Identifier:
1287 break;
1288 }
1289 }
1290
1291 return false;
1292}
1293
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001294bool CursorVisitor::VisitTemplateParameters(
1295 const TemplateParameterList *Params) {
1296 if (!Params)
1297 return false;
1298
1299 for (TemplateParameterList::const_iterator P = Params->begin(),
1300 PEnd = Params->end();
1301 P != PEnd; ++P) {
1302 if (Visit(MakeCXCursor(*P, TU)))
1303 return true;
1304 }
1305
1306 return false;
1307}
1308
Douglas Gregor0b36e612010-08-31 20:37:03 +00001309bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1310 switch (Name.getKind()) {
1311 case TemplateName::Template:
1312 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1313
1314 case TemplateName::OverloadedTemplate:
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001315 // Visit the overloaded template set.
1316 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1317 return true;
1318
Douglas Gregor0b36e612010-08-31 20:37:03 +00001319 return false;
1320
1321 case TemplateName::DependentTemplate:
1322 // FIXME: Visit nested-name-specifier.
1323 return false;
1324
1325 case TemplateName::QualifiedTemplate:
1326 // FIXME: Visit nested-name-specifier.
1327 return Visit(MakeCursorTemplateRef(
1328 Name.getAsQualifiedTemplateName()->getDecl(),
1329 Loc, TU));
Douglas Gregor1aee05d2011-01-15 06:45:20 +00001330
1331 case TemplateName::SubstTemplateTemplateParmPack:
1332 return Visit(MakeCursorTemplateRef(
1333 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1334 Loc, TU));
Douglas Gregor0b36e612010-08-31 20:37:03 +00001335 }
1336
1337 return false;
1338}
1339
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001340bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1341 switch (TAL.getArgument().getKind()) {
1342 case TemplateArgument::Null:
1343 case TemplateArgument::Integral:
Douglas Gregor87dd6972010-12-20 16:52:59 +00001344 case TemplateArgument::Pack:
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001345 return false;
1346
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001347 case TemplateArgument::Type:
1348 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1349 return Visit(TSInfo->getTypeLoc());
1350 return false;
1351
1352 case TemplateArgument::Declaration:
1353 if (Expr *E = TAL.getSourceDeclExpression())
1354 return Visit(MakeCXCursor(E, StmtParent, TU));
1355 return false;
1356
1357 case TemplateArgument::Expression:
1358 if (Expr *E = TAL.getSourceExpression())
1359 return Visit(MakeCXCursor(E, StmtParent, TU));
1360 return false;
1361
1362 case TemplateArgument::Template:
Douglas Gregora7fc9012011-01-05 18:58:31 +00001363 case TemplateArgument::TemplateExpansion:
Douglas Gregorb6744ef2011-03-02 17:09:35 +00001364 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1365 return true;
1366
Douglas Gregora7fc9012011-01-05 18:58:31 +00001367 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregor0b36e612010-08-31 20:37:03 +00001368 TAL.getTemplateNameLoc());
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001369 }
1370
1371 return false;
1372}
1373
Ted Kremeneka0536d82010-05-07 01:04:29 +00001374bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1375 return VisitDeclContext(D);
1376}
1377
Douglas Gregor01829d32010-08-31 14:41:23 +00001378bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1379 return Visit(TL.getUnqualifiedLoc());
1380}
1381
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001382bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00001383 ASTContext &Context = AU->getASTContext();
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001384
1385 // Some builtin types (such as Objective-C's "id", "sel", and
1386 // "Class") have associated declarations. Create cursors for those.
1387 QualType VisitType;
1388 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001389 case BuiltinType::Void:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001390 case BuiltinType::Bool:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001391 case BuiltinType::Char_U:
1392 case BuiltinType::UChar:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001393 case BuiltinType::Char16:
1394 case BuiltinType::Char32:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001395 case BuiltinType::UShort:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001396 case BuiltinType::UInt:
1397 case BuiltinType::ULong:
1398 case BuiltinType::ULongLong:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001399 case BuiltinType::UInt128:
1400 case BuiltinType::Char_S:
1401 case BuiltinType::SChar:
Chris Lattner3f59c972010-12-25 23:25:43 +00001402 case BuiltinType::WChar_U:
1403 case BuiltinType::WChar_S:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001404 case BuiltinType::Short:
1405 case BuiltinType::Int:
1406 case BuiltinType::Long:
1407 case BuiltinType::LongLong:
1408 case BuiltinType::Int128:
1409 case BuiltinType::Float:
1410 case BuiltinType::Double:
1411 case BuiltinType::LongDouble:
1412 case BuiltinType::NullPtr:
1413 case BuiltinType::Overload:
1414 case BuiltinType::Dependent:
John McCall1de4d4e2011-04-07 08:22:57 +00001415 case BuiltinType::UnknownAny:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001416 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001417
Ted Kremenekc4174cc2010-02-18 18:52:18 +00001418 case BuiltinType::ObjCId:
1419 VisitType = Context.getObjCIdType();
1420 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001421
1422 case BuiltinType::ObjCClass:
1423 VisitType = Context.getObjCClassType();
1424 break;
1425
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001426 case BuiltinType::ObjCSel:
1427 VisitType = Context.getObjCSelType();
1428 break;
1429 }
1430
1431 if (!VisitType.isNull()) {
1432 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001433 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001434 TU));
1435 }
1436
1437 return false;
1438}
1439
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001440bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
Richard Smith162e1c12011-04-15 14:24:37 +00001441 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001442}
1443
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001444bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1445 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1446}
1447
1448bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1449 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1450}
1451
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001452bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001453 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001454 // no context information with which we can match up the depth/index in the
1455 // type to the appropriate
1456 return false;
1457}
1458
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001459bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1460 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1461 return true;
1462
John McCallc12c5bb2010-05-15 11:32:37 +00001463 return false;
1464}
1465
1466bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1467 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1468 return true;
1469
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001470 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1471 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1472 TU)))
1473 return true;
1474 }
1475
1476 return false;
1477}
1478
1479bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCallc12c5bb2010-05-15 11:32:37 +00001480 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001481}
1482
Abramo Bagnara075f8f12010-12-10 16:29:40 +00001483bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1484 return Visit(TL.getInnerLoc());
1485}
1486
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001487bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1488 return Visit(TL.getPointeeLoc());
1489}
1490
1491bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1492 return Visit(TL.getPointeeLoc());
1493}
1494
1495bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001500 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001501}
1502
1503bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001504 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001505}
1506
Douglas Gregor01829d32010-08-31 14:41:23 +00001507bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1508 bool SkipResultType) {
1509 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001510 return true;
1511
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001512 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek5dbacb42010-04-07 00:27:13 +00001513 if (Decl *D = TL.getArg(I))
1514 if (Visit(MakeCXCursor(D, TU)))
1515 return true;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001516
1517 return false;
1518}
1519
1520bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1521 if (Visit(TL.getElementLoc()))
1522 return true;
1523
1524 if (Expr *Size = TL.getSizeExpr())
1525 return Visit(MakeCXCursor(Size, StmtParent, TU));
1526
1527 return false;
1528}
1529
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001530bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1531 TemplateSpecializationTypeLoc TL) {
Douglas Gregor0b36e612010-08-31 20:37:03 +00001532 // Visit the template name.
1533 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1534 TL.getTemplateNameLoc()))
1535 return true;
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001536
1537 // Visit the template arguments.
1538 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1539 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1540 return true;
1541
1542 return false;
1543}
1544
Douglas Gregor2332c112010-01-21 20:48:56 +00001545bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1546 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1547}
1548
1549bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1550 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1551 return Visit(TSInfo->getTypeLoc());
1552
1553 return false;
1554}
1555
Douglas Gregor2494dd02011-03-01 01:34:45 +00001556bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1557 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1558 return true;
1559
1560 return false;
1561}
1562
Douglas Gregor94fdffa2011-03-01 20:11:18 +00001563bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1564 DependentTemplateSpecializationTypeLoc TL) {
1565 // Visit the nested-name-specifier, if there is one.
1566 if (TL.getQualifierLoc() &&
1567 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1568 return true;
1569
1570 // Visit the template arguments.
1571 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1572 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1573 return true;
1574
1575 return false;
1576}
1577
Douglas Gregor9e876872011-03-01 18:12:44 +00001578bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1579 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1580 return true;
1581
1582 return Visit(TL.getNamedTypeLoc());
1583}
1584
Douglas Gregor7536dd52010-12-20 02:24:11 +00001585bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1586 return Visit(TL.getPatternLoc());
1587}
1588
Ted Kremenek3064ef92010-08-27 21:34:58 +00001589bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001590 // Visit the nested-name-specifier, if present.
1591 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1592 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1593 return true;
1594
Ted Kremenek3064ef92010-08-27 21:34:58 +00001595 if (D->isDefinition()) {
1596 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1597 E = D->bases_end(); I != E; ++I) {
1598 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1599 return true;
1600 }
1601 }
1602
1603 return VisitTagDecl(D);
1604}
1605
Ted Kremenek09dfa372010-02-18 05:46:33 +00001606bool CursorVisitor::VisitAttributes(Decl *D) {
Sean Huntcf807c42010-08-18 23:23:40 +00001607 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1608 i != e; ++i)
1609 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek09dfa372010-02-18 05:46:33 +00001610 return true;
1611
1612 return false;
1613}
1614
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001615//===----------------------------------------------------------------------===//
1616// Data-recursive visitor methods.
1617//===----------------------------------------------------------------------===//
1618
Ted Kremenek28a71942010-11-13 00:36:47 +00001619namespace {
Ted Kremenek035dc412010-11-13 00:36:50 +00001620#define DEF_JOB(NAME, DATA, KIND)\
1621class NAME : public VisitorJob {\
1622public:\
1623 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1624 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenekf64d8032010-11-18 00:02:32 +00001625 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek035dc412010-11-13 00:36:50 +00001626};
1627
1628DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1629DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001630DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001631DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek60608ec2010-11-17 00:50:47 +00001632DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1633 ExplicitTemplateArgsVisitKind)
Douglas Gregor94d96292011-01-19 20:34:17 +00001634DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001635#undef DEF_JOB
1636
1637class DeclVisit : public VisitorJob {
1638public:
1639 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1640 VisitorJob(parent, VisitorJob::DeclVisitKind,
1641 d, isFirst ? (void*) 1 : (void*) 0) {}
1642 static bool classof(const VisitorJob *VJ) {
Ted Kremenek82f3c502010-11-15 22:23:26 +00001643 return VJ->getKind() == DeclVisitKind;
Ted Kremenek035dc412010-11-13 00:36:50 +00001644 }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001645 Decl *get() const { return static_cast<Decl*>(data[0]); }
1646 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek035dc412010-11-13 00:36:50 +00001647};
Ted Kremenek035dc412010-11-13 00:36:50 +00001648class TypeLocVisit : public VisitorJob {
1649public:
1650 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1651 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1652 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1653
1654 static bool classof(const VisitorJob *VJ) {
1655 return VJ->getKind() == TypeLocVisitKind;
1656 }
1657
Ted Kremenek82f3c502010-11-15 22:23:26 +00001658 TypeLoc get() const {
Ted Kremenekf64d8032010-11-18 00:02:32 +00001659 QualType T = QualType::getFromOpaquePtr(data[0]);
1660 return TypeLoc(T, data[1]);
Ted Kremenek035dc412010-11-13 00:36:50 +00001661 }
1662};
1663
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001664class LabelRefVisit : public VisitorJob {
1665public:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001666 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1667 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001668 labelLoc.getPtrEncoding()) {}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001669
1670 static bool classof(const VisitorJob *VJ) {
1671 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1672 }
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001673 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001674 SourceLocation getLoc() const {
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001675 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001676};
1677class NestedNameSpecifierVisit : public VisitorJob {
1678public:
1679 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1680 CXCursor parent)
1681 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001682 NS, R.getBegin().getPtrEncoding(),
1683 R.getEnd().getPtrEncoding()) {}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001684 static bool classof(const VisitorJob *VJ) {
1685 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1686 }
1687 NestedNameSpecifier *get() const {
1688 return static_cast<NestedNameSpecifier*>(data[0]);
1689 }
1690 SourceRange getSourceRange() const {
1691 SourceLocation A =
1692 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1693 SourceLocation B =
1694 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1695 return SourceRange(A, B);
1696 }
1697};
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001698
1699class NestedNameSpecifierLocVisit : public VisitorJob {
1700public:
1701 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1702 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1703 Qualifier.getNestedNameSpecifier(),
1704 Qualifier.getOpaqueData()) { }
1705
1706 static bool classof(const VisitorJob *VJ) {
1707 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1708 }
1709
1710 NestedNameSpecifierLoc get() const {
1711 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1712 data[1]);
1713 }
1714};
1715
Ted Kremenekf64d8032010-11-18 00:02:32 +00001716class DeclarationNameInfoVisit : public VisitorJob {
1717public:
1718 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1719 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1720 static bool classof(const VisitorJob *VJ) {
1721 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1722 }
1723 DeclarationNameInfo get() const {
1724 Stmt *S = static_cast<Stmt*>(data[0]);
1725 switch (S->getStmtClass()) {
1726 default:
1727 llvm_unreachable("Unhandled Stmt");
1728 case Stmt::CXXDependentScopeMemberExprClass:
1729 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1730 case Stmt::DependentScopeDeclRefExprClass:
1731 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1732 }
1733 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001734};
Ted Kremenekcdba6592010-11-18 00:42:18 +00001735class MemberRefVisit : public VisitorJob {
1736public:
1737 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1738 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001739 L.getPtrEncoding()) {}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1742 }
1743 FieldDecl *get() const {
1744 return static_cast<FieldDecl*>(data[0]);
1745 }
1746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1748 }
1749};
Ted Kremenek28a71942010-11-13 00:36:47 +00001750class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1751 VisitorWorkList &WL;
1752 CXCursor Parent;
1753public:
1754 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1755 : WL(wl), Parent(parent) {}
1756
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001757 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001758 void VisitBlockExpr(BlockExpr *B);
Ted Kremenek28a71942010-11-13 00:36:47 +00001759 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenek083c7e22010-11-13 05:38:03 +00001760 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001761 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001762 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001763 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001764 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001765 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001766 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001767 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001768 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek55b933a2010-11-17 00:50:36 +00001769 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001770 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001771 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek035dc412010-11-13 00:36:50 +00001772 void VisitDeclStmt(DeclStmt *S);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001773 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001774 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001775 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1776 void VisitForStmt(ForStmt *FS);
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001777 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenek28a71942010-11-13 00:36:47 +00001778 void VisitIfStmt(IfStmt *If);
1779 void VisitInitListExpr(InitListExpr *IE);
1780 void VisitMemberExpr(MemberExpr *M);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001781 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001782 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001783 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1784 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00001785 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001786 void VisitStmt(Stmt *S);
1787 void VisitSwitchStmt(SwitchStmt *S);
1788 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek2939b6f2010-11-17 00:50:50 +00001789 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet6ad6f282010-12-07 00:08:36 +00001790 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001791 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenek9d3bf792010-11-17 00:50:43 +00001792 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor94d96292011-01-19 20:34:17 +00001793 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregoree8aff02011-01-04 17:33:58 +00001794
Ted Kremenek28a71942010-11-13 00:36:47 +00001795private:
Ted Kremenekf64d8032010-11-18 00:02:32 +00001796 void AddDeclarationNameInfo(Stmt *S);
1797 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001798 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek60608ec2010-11-17 00:50:47 +00001799 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001800 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenek28a71942010-11-13 00:36:47 +00001801 void AddStmt(Stmt *S);
Ted Kremenek035dc412010-11-13 00:36:50 +00001802 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenek28a71942010-11-13 00:36:47 +00001803 void AddTypeLoc(TypeSourceInfo *TI);
1804 void EnqueueChildren(Stmt *S);
1805};
1806} // end anonyous namespace
1807
Ted Kremenekf64d8032010-11-18 00:02:32 +00001808void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1809 // 'S' should always be non-null, since it comes from the
1810 // statement we are visiting.
1811 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1812}
1813void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1814 SourceRange R) {
1815 if (N)
1816 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1817}
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001818
1819void
1820EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1821 if (Qualifier)
1822 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1823}
1824
Ted Kremenek28a71942010-11-13 00:36:47 +00001825void EnqueueVisitor::AddStmt(Stmt *S) {
1826 if (S)
1827 WL.push_back(StmtVisit(S, Parent));
1828}
Ted Kremenek035dc412010-11-13 00:36:50 +00001829void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001830 if (D)
Ted Kremenek035dc412010-11-13 00:36:50 +00001831 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenek28a71942010-11-13 00:36:47 +00001832}
Ted Kremenek60608ec2010-11-17 00:50:47 +00001833void EnqueueVisitor::
1834 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1835 if (A)
1836 WL.push_back(ExplicitTemplateArgsVisit(
1837 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1838}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001839void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1840 if (D)
1841 WL.push_back(MemberRefVisit(D, L, Parent));
1842}
Ted Kremenek28a71942010-11-13 00:36:47 +00001843void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1844 if (TI)
1845 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1846 }
1847void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremeneka6b70432010-11-12 21:34:09 +00001848 unsigned size = WL.size();
John McCall7502c1d2011-02-13 04:07:26 +00001849 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001850 AddStmt(*Child);
Ted Kremeneka6b70432010-11-12 21:34:09 +00001851 }
1852 if (size == WL.size())
1853 return;
1854 // Now reverse the entries we just added. This will match the DFS
1855 // ordering performed by the worklist.
1856 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1857 std::reverse(I, E);
1858}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001859void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1860 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1861}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001862void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1863 AddDecl(B->getBlockDecl());
1864}
Ted Kremenek28a71942010-11-13 00:36:47 +00001865void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1866 EnqueueChildren(E);
1867 AddTypeLoc(E->getTypeSourceInfo());
1868}
Ted Kremenek083c7e22010-11-13 05:38:03 +00001869void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1870 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1871 E = S->body_rend(); I != E; ++I) {
1872 AddStmt(*I);
1873 }
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001874}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001875void EnqueueVisitor::
1876VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1877 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1878 AddDeclarationNameInfo(E);
Douglas Gregor7c3179c2011-02-28 18:50:33 +00001879 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1880 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001881 if (!E->isImplicitAccess())
1882 AddStmt(E->getBase());
1883}
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001884void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1885 // Enqueue the initializer or constructor arguments.
1886 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1887 AddStmt(E->getConstructorArg(I-1));
1888 // Enqueue the array size, if any.
1889 AddStmt(E->getArraySize());
1890 // Enqueue the allocated type.
1891 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1892 // Enqueue the placement arguments.
1893 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1894 AddStmt(E->getPlacementArg(I-1));
1895}
Ted Kremenek28a71942010-11-13 00:36:47 +00001896void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenek8b8d8c92010-11-13 05:55:56 +00001897 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1898 AddStmt(CE->getArg(I-1));
Ted Kremenek28a71942010-11-13 00:36:47 +00001899 AddStmt(CE->getCallee());
1900 AddStmt(CE->getArg(0));
1901}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001902void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1903 // Visit the name of the type being destroyed.
1904 AddTypeLoc(E->getDestroyedTypeInfo());
1905 // Visit the scope type that looks disturbingly like the nested-name-specifier
1906 // but isn't.
1907 AddTypeLoc(E->getScopeTypeInfo());
1908 // Visit the nested-name-specifier.
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001909 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1910 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001911 // Visit base expression.
1912 AddStmt(E->getBase());
1913}
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001914void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1915 AddTypeLoc(E->getTypeSourceInfo());
1916}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001917void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1918 EnqueueChildren(E);
1919 AddTypeLoc(E->getTypeSourceInfo());
1920}
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001921void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1922 EnqueueChildren(E);
1923 if (E->isTypeOperand())
1924 AddTypeLoc(E->getTypeOperandSourceInfo());
1925}
Ted Kremenek55b933a2010-11-17 00:50:36 +00001926
1927void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1928 *E) {
1929 EnqueueChildren(E);
1930 AddTypeLoc(E->getTypeSourceInfo());
1931}
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001932void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1933 EnqueueChildren(E);
1934 if (E->isTypeOperand())
1935 AddTypeLoc(E->getTypeOperandSourceInfo());
1936}
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001937void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00001938 if (DR->hasExplicitTemplateArgs()) {
1939 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1940 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001941 WL.push_back(DeclRefExprParts(DR, Parent));
1942}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001943void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1944 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1945 AddDeclarationNameInfo(E);
Douglas Gregor00cf3cc2011-02-25 20:49:16 +00001946 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenekf64d8032010-11-18 00:02:32 +00001947}
Ted Kremenek035dc412010-11-13 00:36:50 +00001948void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1949 unsigned size = WL.size();
1950 bool isFirst = true;
1951 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1952 D != DEnd; ++D) {
1953 AddDecl(*D, isFirst);
1954 isFirst = false;
1955 }
1956 if (size == WL.size())
1957 return;
1958 // Now reverse the entries we just added. This will match the DFS
1959 // ordering performed by the worklist.
1960 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1961 std::reverse(I, E);
1962}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001963void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1964 AddStmt(E->getInit());
1965 typedef DesignatedInitExpr::Designator Designator;
1966 for (DesignatedInitExpr::reverse_designators_iterator
1967 D = E->designators_rbegin(), DEnd = E->designators_rend();
1968 D != DEnd; ++D) {
1969 if (D->isFieldDesignator()) {
1970 if (FieldDecl *Field = D->getField())
1971 AddMemberRef(Field, D->getFieldLoc());
1972 continue;
1973 }
1974 if (D->isArrayDesignator()) {
1975 AddStmt(E->getArrayIndex(*D));
1976 continue;
1977 }
1978 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1979 AddStmt(E->getArrayRangeEnd(*D));
1980 AddStmt(E->getArrayRangeStart(*D));
1981 }
1982}
Ted Kremenek28a71942010-11-13 00:36:47 +00001983void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1984 EnqueueChildren(E);
1985 AddTypeLoc(E->getTypeInfoAsWritten());
1986}
1987void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1988 AddStmt(FS->getBody());
1989 AddStmt(FS->getInc());
1990 AddStmt(FS->getCond());
1991 AddDecl(FS->getConditionVariable());
1992 AddStmt(FS->getInit());
1993}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001994void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1995 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1996}
Ted Kremenek28a71942010-11-13 00:36:47 +00001997void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
1998 AddStmt(If->getElse());
1999 AddStmt(If->getThen());
2000 AddStmt(If->getCond());
2001 AddDecl(If->getConditionVariable());
2002}
2003void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
2004 // We care about the syntactic form of the initializer list, only.
2005 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2006 IE = Syntactic;
2007 EnqueueChildren(IE);
2008}
2009void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor89629a72010-11-17 17:15:08 +00002010 WL.push_back(MemberExprParts(M, Parent));
2011
2012 // If the base of the member access expression is an implicit 'this', don't
2013 // visit it.
2014 // FIXME: If we ever want to show these implicit accesses, this will be
2015 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor75e85042011-03-02 21:06:53 +00002016 if (!M->isImplicitAccess())
2017 AddStmt(M->getBase());
Ted Kremenek28a71942010-11-13 00:36:47 +00002018}
Ted Kremenek73d15c42010-11-13 01:09:29 +00002019void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2020 AddTypeLoc(E->getEncodedTypeSourceInfo());
2021}
Ted Kremenek28a71942010-11-13 00:36:47 +00002022void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2023 EnqueueChildren(M);
2024 AddTypeLoc(M->getClassReceiverTypeInfo());
2025}
Ted Kremenekcdba6592010-11-18 00:42:18 +00002026void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2027 // Visit the components of the offsetof expression.
2028 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2029 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2030 const OffsetOfNode &Node = E->getComponent(I-1);
2031 switch (Node.getKind()) {
2032 case OffsetOfNode::Array:
2033 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2034 break;
2035 case OffsetOfNode::Field:
Abramo Bagnara06dec892011-03-12 09:45:03 +00002036 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenekcdba6592010-11-18 00:42:18 +00002037 break;
2038 case OffsetOfNode::Identifier:
2039 case OffsetOfNode::Base:
2040 continue;
2041 }
2042 }
2043 // Visit the type into which we're computing the offset.
2044 AddTypeLoc(E->getTypeSourceInfo());
2045}
Ted Kremenek28a71942010-11-13 00:36:47 +00002046void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00002047 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenek60458782010-11-12 21:34:16 +00002048 WL.push_back(OverloadExprParts(E, Parent));
2049}
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00002050void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2051 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00002052 EnqueueChildren(E);
2053 if (E->isArgumentType())
2054 AddTypeLoc(E->getArgumentTypeInfo());
2055}
Ted Kremenek28a71942010-11-13 00:36:47 +00002056void EnqueueVisitor::VisitStmt(Stmt *S) {
2057 EnqueueChildren(S);
2058}
2059void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2060 AddStmt(S->getBody());
2061 AddStmt(S->getCond());
2062 AddDecl(S->getConditionVariable());
2063}
Ted Kremenekfafa75a2010-11-17 00:50:39 +00002064
Ted Kremenek28a71942010-11-13 00:36:47 +00002065void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2066 AddStmt(W->getBody());
2067 AddStmt(W->getCond());
2068 AddDecl(W->getConditionVariable());
2069}
Ted Kremenek2939b6f2010-11-17 00:50:50 +00002070void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2071 AddTypeLoc(E->getQueriedTypeSourceInfo());
2072}
Francois Pichet6ad6f282010-12-07 00:08:36 +00002073
2074void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet6ad6f282010-12-07 00:08:36 +00002075 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichet0a03a3f2010-12-08 09:11:05 +00002076 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet6ad6f282010-12-07 00:08:36 +00002077}
2078
Ted Kremenek28a71942010-11-13 00:36:47 +00002079void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2080 VisitOverloadExpr(U);
2081 if (!U->isImplicitAccess())
2082 AddStmt(U->getBase());
2083}
Ted Kremenek9d3bf792010-11-17 00:50:43 +00002084void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2085 AddStmt(E->getSubExpr());
2086 AddTypeLoc(E->getWrittenTypeInfo());
2087}
Douglas Gregor94d96292011-01-19 20:34:17 +00002088void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2089 WL.push_back(SizeOfPackExprParts(E, Parent));
2090}
Ted Kremenek60458782010-11-12 21:34:16 +00002091
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002092void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenek28a71942010-11-13 00:36:47 +00002093 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002094}
2095
2096bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2097 if (RegionOfInterest.isValid()) {
2098 SourceRange Range = getRawCursorExtent(C);
2099 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2100 return false;
2101 }
2102 return true;
2103}
2104
2105bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2106 while (!WL.empty()) {
2107 // Dequeue the worklist item.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002108 VisitorJob LI = WL.back();
2109 WL.pop_back();
2110
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002111 // Set the Parent field, then back to its old value once we're done.
2112 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2113
2114 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00002115 case VisitorJob::DeclVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002116 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenekf1107452010-11-12 18:26:56 +00002117 if (!D)
2118 continue;
2119
2120 // For now, perform default visitation for Decls.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002121 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenekf1107452010-11-12 18:26:56 +00002122 return true;
2123
2124 continue;
2125 }
Ted Kremenek60608ec2010-11-17 00:50:47 +00002126 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2127 const ExplicitTemplateArgumentList *ArgList =
2128 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2129 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2130 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2131 Arg != ArgEnd; ++Arg) {
2132 if (VisitTemplateArgumentLoc(*Arg))
2133 return true;
2134 }
2135 continue;
2136 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002137 case VisitorJob::TypeLocVisitKind: {
2138 // Perform default visitation for TypeLocs.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002139 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002140 return true;
2141 continue;
2142 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002143 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002144 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremeneke7455012011-02-23 04:54:51 +00002145 if (LabelStmt *stmt = LS->getStmt()) {
2146 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2147 TU))) {
2148 return true;
2149 }
2150 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002151 continue;
2152 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002153
Ted Kremenekf64d8032010-11-18 00:02:32 +00002154 case VisitorJob::NestedNameSpecifierVisitKind: {
2155 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2156 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2157 return true;
2158 continue;
2159 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002160
2161 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2162 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2163 if (VisitNestedNameSpecifierLoc(V->get()))
2164 return true;
2165 continue;
2166 }
2167
Ted Kremenekf64d8032010-11-18 00:02:32 +00002168 case VisitorJob::DeclarationNameInfoVisitKind: {
2169 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2170 ->get()))
2171 return true;
2172 continue;
2173 }
Ted Kremenekcdba6592010-11-18 00:42:18 +00002174 case VisitorJob::MemberRefVisitKind: {
2175 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2176 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2177 return true;
2178 continue;
2179 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002180 case VisitorJob::StmtVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002181 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002182 if (!S)
2183 continue;
2184
Ted Kremenekf1107452010-11-12 18:26:56 +00002185 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002186 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenekcdba6592010-11-18 00:42:18 +00002187 if (!IsInRegionOfInterest(Cursor))
2188 continue;
2189 switch (Visitor(Cursor, Parent, ClientData)) {
2190 case CXChildVisit_Break: return true;
2191 case CXChildVisit_Continue: break;
2192 case CXChildVisit_Recurse:
2193 EnqueueWorkList(WL, S);
Ted Kremenek82f3c502010-11-15 22:23:26 +00002194 break;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002195 }
Ted Kremenek82f3c502010-11-15 22:23:26 +00002196 continue;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002197 }
2198 case VisitorJob::MemberExprPartsKind: {
2199 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002200 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002201
2202 // Visit the nested-name-specifier
Douglas Gregor40d96a62011-02-28 21:54:11 +00002203 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2204 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002205 return true;
2206
2207 // Visit the declaration name.
2208 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2209 return true;
2210
2211 // Visit the explicitly-specified template arguments, if any.
2212 if (M->hasExplicitTemplateArgs()) {
2213 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2214 *ArgEnd = Arg + M->getNumTemplateArgs();
2215 Arg != ArgEnd; ++Arg) {
2216 if (VisitTemplateArgumentLoc(*Arg))
2217 return true;
2218 }
2219 }
2220 continue;
2221 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002222 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002223 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002224 // Visit nested-name-specifier, if present.
Douglas Gregor40d96a62011-02-28 21:54:11 +00002225 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2226 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002227 return true;
2228 // Visit declaration name.
2229 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2230 return true;
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002231 continue;
2232 }
Ted Kremenek60458782010-11-12 21:34:16 +00002233 case VisitorJob::OverloadExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002234 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenek60458782010-11-12 21:34:16 +00002235 // Visit the nested-name-specifier.
Douglas Gregor4c9be892011-02-28 20:01:57 +00002236 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2237 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek60458782010-11-12 21:34:16 +00002238 return true;
2239 // Visit the declaration name.
2240 if (VisitDeclarationNameInfo(O->getNameInfo()))
2241 return true;
2242 // Visit the overloaded declaration reference.
2243 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2244 return true;
Ted Kremenek60458782010-11-12 21:34:16 +00002245 continue;
2246 }
Douglas Gregor94d96292011-01-19 20:34:17 +00002247 case VisitorJob::SizeOfPackExprPartsKind: {
2248 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2249 NamedDecl *Pack = E->getPack();
2250 if (isa<TemplateTypeParmDecl>(Pack)) {
2251 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2252 E->getPackLoc(), TU)))
2253 return true;
2254
2255 continue;
2256 }
2257
2258 if (isa<TemplateTemplateParmDecl>(Pack)) {
2259 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2260 E->getPackLoc(), TU)))
2261 return true;
2262
2263 continue;
2264 }
2265
2266 // Non-type template parameter packs and function parameter packs are
2267 // treated like DeclRefExpr cursors.
2268 continue;
2269 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002270 }
2271 }
2272 return false;
2273}
2274
Ted Kremenekcdba6592010-11-18 00:42:18 +00002275bool CursorVisitor::Visit(Stmt *S) {
Ted Kremenekd1ded662010-11-15 23:31:32 +00002276 VisitorWorkList *WL = 0;
2277 if (!WorkListFreeList.empty()) {
2278 WL = WorkListFreeList.back();
2279 WL->clear();
2280 WorkListFreeList.pop_back();
2281 }
2282 else {
2283 WL = new VisitorWorkList();
2284 WorkListCache.push_back(WL);
2285 }
2286 EnqueueWorkList(*WL, S);
2287 bool result = RunVisitorWorkList(*WL);
2288 WorkListFreeList.push_back(WL);
2289 return result;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002290}
2291
2292//===----------------------------------------------------------------------===//
2293// Misc. API hooks.
2294//===----------------------------------------------------------------------===//
2295
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002296static llvm::sys::Mutex EnableMultithreadingMutex;
2297static bool EnabledMultithreading;
2298
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002299extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002300CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2301 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002302 // Disable pretty stack trace functionality, which will otherwise be a very
2303 // poor citizen of the world and set up all sorts of signal handlers.
2304 llvm::DisablePrettyStackTrace = true;
2305
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002306 // We use crash recovery to make some of our APIs more reliable, implicitly
2307 // enable it.
2308 llvm::CrashRecoveryContext::Enable();
2309
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002310 // Enable support for multithreading in LLVM.
2311 {
2312 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2313 if (!EnabledMultithreading) {
2314 llvm::llvm_start_multithreaded();
2315 EnabledMultithreading = true;
2316 }
2317 }
2318
Douglas Gregora030b7c2010-01-22 20:35:53 +00002319 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002320 if (excludeDeclarationsFromPCH)
2321 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002322 if (displayDiagnostics)
2323 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002324 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002325}
2326
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002327void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002328 if (CIdx)
2329 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002330}
2331
Ted Kremenekd2427dd2011-03-18 23:05:39 +00002332void clang_toggleCrashRecovery(unsigned isEnabled) {
2333 if (isEnabled)
2334 llvm::CrashRecoveryContext::Enable();
2335 else
2336 llvm::CrashRecoveryContext::Disable();
2337}
2338
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002339CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002340 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002341 if (!CIdx)
2342 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002343
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002344 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002345 FileSystemOptions FileSystemOpts;
2346 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002347
Douglas Gregor28019772010-04-05 23:52:57 +00002348 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremeneka60ed472010-11-16 08:15:36 +00002349 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002350 CXXIdx->getOnlyLocalDecls(),
2351 0, 0, true);
Ted Kremeneka60ed472010-11-16 08:15:36 +00002352 return MakeCXTranslationUnit(TU);
Steve Naroff600866c2009-08-27 19:51:58 +00002353}
2354
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002355unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002356 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002357 CXTranslationUnit_CacheCompletionResults |
2358 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002359}
2360
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002361CXTranslationUnit
2362clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2363 const char *source_filename,
2364 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002365 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002366 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002367 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor5a430212010-07-21 18:52:53 +00002368 return clang_parseTranslationUnit(CIdx, source_filename,
2369 command_line_args, num_command_line_args,
2370 unsaved_files, num_unsaved_files,
2371 CXTranslationUnit_DetailedPreprocessingRecord);
2372}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002373
2374struct ParseTranslationUnitInfo {
2375 CXIndex CIdx;
2376 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002377 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002378 int num_command_line_args;
2379 struct CXUnsavedFile *unsaved_files;
2380 unsigned num_unsaved_files;
2381 unsigned options;
2382 CXTranslationUnit result;
2383};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002384static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002385 ParseTranslationUnitInfo *PTUI =
2386 static_cast<ParseTranslationUnitInfo*>(UserData);
2387 CXIndex CIdx = PTUI->CIdx;
2388 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002389 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002390 int num_command_line_args = PTUI->num_command_line_args;
2391 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2392 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2393 unsigned options = PTUI->options;
2394 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002395
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002396 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002397 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002398
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002399 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2400
Douglas Gregor44c181a2010-07-23 00:33:23 +00002401 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002402 bool CompleteTranslationUnit
2403 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002404 bool CacheCodeCompetionResults
2405 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002406 bool CXXPrecompilePreamble
2407 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2408 bool CXXChainedPCH
2409 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002410
Douglas Gregor5352ac02010-01-28 00:27:43 +00002411 // Configure the diagnostics.
2412 DiagnosticOptions DiagOpts;
Ted Kremenek25a11e12011-03-22 01:15:24 +00002413 llvm::IntrusiveRefCntPtr<Diagnostic>
2414 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2415 command_line_args));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002416
Ted Kremenek25a11e12011-03-22 01:15:24 +00002417 // Recover resources if we crash before exiting this function.
2418 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2419 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2420 DiagCleanup(Diags.getPtr());
2421
2422 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2423 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2424
2425 // Recover resources if we crash before exiting this function.
2426 llvm::CrashRecoveryContextCleanupRegistrar<
2427 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2428
Douglas Gregor4db64a42010-01-23 00:14:00 +00002429 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002430 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002431 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002432 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002433 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2434 Buffer));
Douglas Gregor4db64a42010-01-23 00:14:00 +00002435 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002436
Ted Kremenek25a11e12011-03-22 01:15:24 +00002437 llvm::OwningPtr<std::vector<const char *> >
2438 Args(new std::vector<const char*>());
2439
2440 // Recover resources if we crash before exiting this method.
2441 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2442 ArgsCleanup(Args.get());
2443
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002444 // Since the Clang C library is primarily used by batch tools dealing with
2445 // (often very broken) source code, where spell-checking can have a
2446 // significant negative impact on performance (particularly when
2447 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002448 // Only do this if we haven't found a spell-checking-related argument.
2449 bool FoundSpellCheckingArgument = false;
2450 for (int I = 0; I != num_command_line_args; ++I) {
2451 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2452 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2453 FoundSpellCheckingArgument = true;
2454 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002455 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002456 }
2457 if (!FoundSpellCheckingArgument)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002458 Args->push_back("-fno-spell-checking");
Douglas Gregorb10daed2010-10-11 16:52:23 +00002459
Ted Kremenek25a11e12011-03-22 01:15:24 +00002460 Args->insert(Args->end(), command_line_args,
2461 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002462
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002463 // The 'source_filename' argument is optional. If the caller does not
2464 // specify it then it is assumed that the source file is specified
2465 // in the actual argument list.
2466 // Put the source file after command_line_args otherwise if '-x' flag is
2467 // present it will be unused.
2468 if (source_filename)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002469 Args->push_back(source_filename);
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002470
Douglas Gregor44c181a2010-07-23 00:33:23 +00002471 // Do we need the detailed preprocessing record?
2472 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek25a11e12011-03-22 01:15:24 +00002473 Args->push_back("-Xclang");
2474 Args->push_back("-detailed-preprocessing-record");
Douglas Gregor44c181a2010-07-23 00:33:23 +00002475 }
2476
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002477 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002478 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek4ee99262011-03-22 20:16:19 +00002479 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2480 /* vector::data() not portable */,
2481 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002482 Diags,
2483 CXXIdx->getClangResourcesPath(),
2484 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002485 /*CaptureDiagnostics=*/true,
Ted Kremenek4ee99262011-03-22 20:16:19 +00002486 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek25a11e12011-03-22 01:15:24 +00002487 RemappedFiles->size(),
Argyrios Kyrtzidis299a4a92011-03-08 23:35:24 +00002488 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002489 PrecompilePreamble,
2490 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002491 CacheCodeCompetionResults,
2492 CXXPrecompilePreamble,
2493 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002494
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002495 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002496 // Make sure to check that 'Unit' is non-NULL.
2497 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2498 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2499 DEnd = Unit->stored_diag_end();
2500 D != DEnd; ++D) {
2501 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2502 CXString Msg = clang_formatDiagnostic(&Diag,
2503 clang_defaultDiagnosticDisplayOptions());
2504 fprintf(stderr, "%s\n", clang_getCString(Msg));
2505 clang_disposeString(Msg);
2506 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002507#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002508 // On Windows, force a flush, since there may be multiple copies of
2509 // stderr and stdout in the file system, all with different buffers
2510 // but writing to the same device.
2511 fflush(stderr);
2512#endif
2513 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002514 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002515
Ted Kremeneka60ed472010-11-16 08:15:36 +00002516 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002517}
2518CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2519 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002520 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002521 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002522 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002523 unsigned num_unsaved_files,
2524 unsigned options) {
2525 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002526 num_command_line_args, unsaved_files,
2527 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002528 llvm::CrashRecoveryContext CRC;
2529
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002530 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002531 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2532 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2533 fprintf(stderr, " 'command_line_args' : [");
2534 for (int i = 0; i != num_command_line_args; ++i) {
2535 if (i)
2536 fprintf(stderr, ", ");
2537 fprintf(stderr, "'%s'", command_line_args[i]);
2538 }
2539 fprintf(stderr, "],\n");
2540 fprintf(stderr, " 'unsaved_files' : [");
2541 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2542 if (i)
2543 fprintf(stderr, ", ");
2544 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2545 unsaved_files[i].Length);
2546 }
2547 fprintf(stderr, "],\n");
2548 fprintf(stderr, " 'options' : %d,\n", options);
2549 fprintf(stderr, "}\n");
2550
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002551 return 0;
2552 }
2553
2554 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002555}
2556
Douglas Gregor19998442010-08-13 15:35:05 +00002557unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2558 return CXSaveTranslationUnit_None;
2559}
2560
2561int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2562 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002563 if (!TU)
2564 return 1;
2565
Ted Kremeneka60ed472010-11-16 08:15:36 +00002566 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002567}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002568
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002569void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002570 if (CTUnit) {
2571 // If the translation unit has been marked as unsafe to free, just discard
2572 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002573 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002574 return;
2575
Ted Kremeneka60ed472010-11-16 08:15:36 +00002576 delete static_cast<ASTUnit *>(CTUnit->TUData);
2577 disposeCXStringPool(CTUnit->StringPool);
2578 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002579 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002580}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002581
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002582unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2583 return CXReparse_None;
2584}
2585
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002586struct ReparseTranslationUnitInfo {
2587 CXTranslationUnit TU;
2588 unsigned num_unsaved_files;
2589 struct CXUnsavedFile *unsaved_files;
2590 unsigned options;
2591 int result;
2592};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002593
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002594static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002595 ReparseTranslationUnitInfo *RTUI =
2596 static_cast<ReparseTranslationUnitInfo*>(UserData);
2597 CXTranslationUnit TU = RTUI->TU;
2598 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2599 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2600 unsigned options = RTUI->options;
2601 (void) options;
2602 RTUI->result = 1;
2603
Douglas Gregorabc563f2010-07-19 21:46:24 +00002604 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002605 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002606
Ted Kremeneka60ed472010-11-16 08:15:36 +00002607 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002608 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002609
Ted Kremenek25a11e12011-03-22 01:15:24 +00002610 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2611 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2612
2613 // Recover resources if we crash before exiting this function.
2614 llvm::CrashRecoveryContextCleanupRegistrar<
2615 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2616
Douglas Gregorabc563f2010-07-19 21:46:24 +00002617 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2618 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2619 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002620 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002621 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2622 Buffer));
Douglas Gregorabc563f2010-07-19 21:46:24 +00002623 }
2624
Ted Kremenek4ee99262011-03-22 20:16:19 +00002625 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2626 RemappedFiles->size()))
Douglas Gregor593b0c12010-09-23 18:47:53 +00002627 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002628}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002629
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002630int clang_reparseTranslationUnit(CXTranslationUnit TU,
2631 unsigned num_unsaved_files,
2632 struct CXUnsavedFile *unsaved_files,
2633 unsigned options) {
2634 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2635 options, 0 };
2636 llvm::CrashRecoveryContext CRC;
2637
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002638 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002639 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002640 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002641 return 1;
2642 }
2643
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002644
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002645 return RTUI.result;
2646}
2647
Douglas Gregordf95a132010-08-09 20:45:32 +00002648
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002649CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002650 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002651 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002652
Ted Kremeneka60ed472010-11-16 08:15:36 +00002653 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002654 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002655}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002656
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002657CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002658 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002659 return Result;
2660}
2661
Ted Kremenekfb480492010-01-13 21:46:36 +00002662} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002663
Ted Kremenekfb480492010-01-13 21:46:36 +00002664//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002665// CXSourceLocation and CXSourceRange Operations.
2666//===----------------------------------------------------------------------===//
2667
Douglas Gregorb9790342010-01-22 21:44:22 +00002668extern "C" {
2669CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002670 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002671 return Result;
2672}
2673
2674unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002675 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2676 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2677 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002678}
2679
2680CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2681 CXFile file,
2682 unsigned line,
2683 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002684 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002685 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002686
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002687 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002688 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002689 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002690 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002691 = CXXUnit->getSourceManager().getLocation(File, line, column);
2692 if (SLoc.isInvalid()) {
2693 if (Logging)
2694 llvm::errs() << "clang_getLocation(\"" << File->getName()
2695 << "\", " << line << ", " << column << ") = invalid\n";
2696 return clang_getNullLocation();
2697 }
2698
2699 if (Logging)
2700 llvm::errs() << "clang_getLocation(\"" << File->getName()
2701 << "\", " << line << ", " << column << ") = "
2702 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002703
2704 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2705}
2706
2707CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2708 CXFile file,
2709 unsigned offset) {
2710 if (!tu || !file)
2711 return clang_getNullLocation();
2712
Ted Kremeneka60ed472010-11-16 08:15:36 +00002713 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002714 SourceLocation Start
2715 = CXXUnit->getSourceManager().getLocation(
2716 static_cast<const FileEntry *>(file),
2717 1, 1);
2718 if (Start.isInvalid()) return clang_getNullLocation();
2719
2720 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2721
2722 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002723
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002724 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002725}
2726
Douglas Gregor5352ac02010-01-28 00:27:43 +00002727CXSourceRange clang_getNullRange() {
2728 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2729 return Result;
2730}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002731
Douglas Gregor5352ac02010-01-28 00:27:43 +00002732CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2733 if (begin.ptr_data[0] != end.ptr_data[0] ||
2734 begin.ptr_data[1] != end.ptr_data[1])
2735 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002736
2737 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002738 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002739 return Result;
2740}
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002741} // end: extern "C"
Douglas Gregorb9790342010-01-22 21:44:22 +00002742
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002743static void createNullLocation(CXFile *file, unsigned *line,
2744 unsigned *column, unsigned *offset) {
2745 if (file)
2746 *file = 0;
2747 if (line)
2748 *line = 0;
2749 if (column)
2750 *column = 0;
2751 if (offset)
2752 *offset = 0;
2753 return;
2754}
2755
2756extern "C" {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002757void clang_getInstantiationLocation(CXSourceLocation location,
2758 CXFile *file,
2759 unsigned *line,
2760 unsigned *column,
2761 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002762 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2763
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002764 if (!location.ptr_data[0] || Loc.isInvalid()) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002765 createNullLocation(file, line, column, offset);
Douglas Gregor46766dc2010-01-26 19:19:08 +00002766 return;
2767 }
2768
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002769 const SourceManager &SM =
2770 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002771 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002772
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002773 // Check that the FileID is invalid on the instantiation location.
2774 // This can manifest in invalid code.
2775 FileID fileID = SM.getFileID(InstLoc);
Douglas Gregore23ac652011-04-20 00:21:03 +00002776 bool Invalid = false;
2777 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
2778 if (!sloc.isFile() || Invalid) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002779 createNullLocation(file, line, column, offset);
2780 return;
2781 }
2782
Douglas Gregor1db19de2010-01-19 21:36:55 +00002783 if (file)
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002784 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002785 if (line)
2786 *line = SM.getInstantiationLineNumber(InstLoc);
2787 if (column)
2788 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002789 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002790 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002791}
2792
Douglas Gregora9b06d42010-11-09 06:24:54 +00002793void clang_getSpellingLocation(CXSourceLocation location,
2794 CXFile *file,
2795 unsigned *line,
2796 unsigned *column,
2797 unsigned *offset) {
2798 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2799
2800 if (!location.ptr_data[0] || Loc.isInvalid()) {
2801 if (file)
2802 *file = 0;
2803 if (line)
2804 *line = 0;
2805 if (column)
2806 *column = 0;
2807 if (offset)
2808 *offset = 0;
2809 return;
2810 }
2811
2812 const SourceManager &SM =
2813 *static_cast<const SourceManager*>(location.ptr_data[0]);
2814 SourceLocation SpellLoc = Loc;
2815 if (SpellLoc.isMacroID()) {
2816 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2817 if (SimpleSpellingLoc.isFileID() &&
2818 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2819 SpellLoc = SimpleSpellingLoc;
2820 else
2821 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2822 }
2823
2824 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2825 FileID FID = LocInfo.first;
2826 unsigned FileOffset = LocInfo.second;
2827
2828 if (file)
2829 *file = (void *)SM.getFileEntryForID(FID);
2830 if (line)
2831 *line = SM.getLineNumber(FID, FileOffset);
2832 if (column)
2833 *column = SM.getColumnNumber(FID, FileOffset);
2834 if (offset)
2835 *offset = FileOffset;
2836}
2837
Douglas Gregor1db19de2010-01-19 21:36:55 +00002838CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002839 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002840 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002841 return Result;
2842}
2843
2844CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002845 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002846 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002847 return Result;
2848}
2849
Douglas Gregorb9790342010-01-22 21:44:22 +00002850} // end: extern "C"
2851
Douglas Gregor1db19de2010-01-19 21:36:55 +00002852//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002853// CXFile Operations.
2854//===----------------------------------------------------------------------===//
2855
2856extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002857CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002858 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002859 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002860
Steve Naroff88145032009-10-27 14:35:18 +00002861 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002862 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002863}
2864
2865time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002866 if (!SFile)
2867 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002868
Steve Naroff88145032009-10-27 14:35:18 +00002869 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2870 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002871}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002872
Douglas Gregorb9790342010-01-22 21:44:22 +00002873CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2874 if (!tu)
2875 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002876
Ted Kremeneka60ed472010-11-16 08:15:36 +00002877 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002878
Douglas Gregorb9790342010-01-22 21:44:22 +00002879 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002880 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002881}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002882
Ted Kremenekfb480492010-01-13 21:46:36 +00002883} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002884
Ted Kremenekfb480492010-01-13 21:46:36 +00002885//===----------------------------------------------------------------------===//
2886// CXCursor Operations.
2887//===----------------------------------------------------------------------===//
2888
Ted Kremenekfb480492010-01-13 21:46:36 +00002889static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002890 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2891 return getDeclFromExpr(CE->getSubExpr());
2892
Ted Kremenekfb480492010-01-13 21:46:36 +00002893 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2894 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002895 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2896 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002897 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2898 return ME->getMemberDecl();
2899 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2900 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002901 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002902 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002903
Ted Kremenekfb480492010-01-13 21:46:36 +00002904 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2905 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002906 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2907 if (!CE->isElidable())
2908 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002909 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2910 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002911
Douglas Gregordb1314e2010-10-01 21:11:22 +00002912 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2913 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002914 if (SubstNonTypeTemplateParmPackExpr *NTTP
2915 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2916 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002917 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2918 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2919 isa<ParmVarDecl>(SizeOfPack->getPack()))
2920 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002921
Ted Kremenekfb480492010-01-13 21:46:36 +00002922 return 0;
2923}
2924
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002925static SourceLocation getLocationFromExpr(Expr *E) {
2926 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2927 return /*FIXME:*/Msg->getLeftLoc();
2928 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2929 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002930 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2931 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002932 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2933 return Member->getMemberLoc();
2934 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2935 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002936 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2937 return SizeOfPack->getPackLoc();
2938
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002939 return E->getLocStart();
2940}
2941
Ted Kremenekfb480492010-01-13 21:46:36 +00002942extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002943
2944unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002945 CXCursorVisitor visitor,
2946 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002947 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00002948 getCursorASTUnit(parent)->getMaxPCHLevel(),
2949 false);
Douglas Gregorb1373d02010-01-20 20:59:29 +00002950 return CursorVis.VisitChildren(parent);
2951}
2952
David Chisnall3387c652010-11-03 14:12:26 +00002953#ifndef __has_feature
2954#define __has_feature(x) 0
2955#endif
2956#if __has_feature(blocks)
2957typedef enum CXChildVisitResult
2958 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2959
2960static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2961 CXClientData client_data) {
2962 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2963 return block(cursor, parent);
2964}
2965#else
2966// If we are compiled with a compiler that doesn't have native blocks support,
2967// define and call the block manually, so the
2968typedef struct _CXChildVisitResult
2969{
2970 void *isa;
2971 int flags;
2972 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002973 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2974 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002975} *CXCursorVisitorBlock;
2976
2977static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2978 CXClientData client_data) {
2979 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2980 return block->invoke(block, cursor, parent);
2981}
2982#endif
2983
2984
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002985unsigned clang_visitChildrenWithBlock(CXCursor parent,
2986 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002987 return clang_visitChildren(parent, visitWithBlock, block);
2988}
2989
Douglas Gregor78205d42010-01-20 21:45:58 +00002990static CXString getDeclSpelling(Decl *D) {
2991 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00002992 if (!ND) {
2993 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2994 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2995 return createCXString(Property->getIdentifier()->getName());
2996
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002997 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00002998 }
2999
Douglas Gregor78205d42010-01-20 21:45:58 +00003000 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003001 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003002
Douglas Gregor78205d42010-01-20 21:45:58 +00003003 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
3004 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3005 // and returns different names. NamedDecl returns the class name and
3006 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003007 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003008
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003009 if (isa<UsingDirectiveDecl>(D))
3010 return createCXString("");
3011
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00003012 llvm::SmallString<1024> S;
3013 llvm::raw_svector_ostream os(S);
3014 ND->printName(os);
3015
3016 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00003017}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003018
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003019CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003020 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003021 return clang_getTranslationUnitSpelling(
3022 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003023
Steve Narofff334b4e2009-09-02 18:26:48 +00003024 if (clang_isReference(C.kind)) {
3025 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00003026 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00003027 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003028 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003029 }
3030 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00003031 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003032 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003033 }
3034 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00003035 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00003036 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003037 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003038 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00003039 case CXCursor_CXXBaseSpecifier: {
3040 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3041 return createCXString(B->getType().getAsString());
3042 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003043 case CXCursor_TypeRef: {
3044 TypeDecl *Type = getCursorTypeRef(C).first;
3045 assert(Type && "Missing type decl");
3046
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003047 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3048 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003049 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003050 case CXCursor_TemplateRef: {
3051 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00003052 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003053
3054 return createCXString(Template->getNameAsString());
3055 }
Douglas Gregor69319002010-08-31 23:48:11 +00003056
3057 case CXCursor_NamespaceRef: {
3058 NamedDecl *NS = getCursorNamespaceRef(C).first;
3059 assert(NS && "Missing namespace decl");
3060
3061 return createCXString(NS->getNameAsString());
3062 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003063
Douglas Gregora67e03f2010-09-09 21:42:20 +00003064 case CXCursor_MemberRef: {
3065 FieldDecl *Field = getCursorMemberRef(C).first;
3066 assert(Field && "Missing member decl");
3067
3068 return createCXString(Field->getNameAsString());
3069 }
3070
Douglas Gregor36897b02010-09-10 00:22:18 +00003071 case CXCursor_LabelRef: {
3072 LabelStmt *Label = getCursorLabelRef(C).first;
3073 assert(Label && "Missing label");
3074
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003075 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003076 }
3077
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003078 case CXCursor_OverloadedDeclRef: {
3079 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3080 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3081 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3082 return createCXString(ND->getNameAsString());
3083 return createCXString("");
3084 }
3085 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3086 return createCXString(E->getName().getAsString());
3087 OverloadedTemplateStorage *Ovl
3088 = Storage.get<OverloadedTemplateStorage*>();
3089 if (Ovl->size() == 0)
3090 return createCXString("");
3091 return createCXString((*Ovl->begin())->getNameAsString());
3092 }
3093
Daniel Dunbaracca7252009-11-30 20:42:49 +00003094 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003095 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003096 }
3097 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003098
3099 if (clang_isExpression(C.kind)) {
3100 Decl *D = getDeclFromExpr(getCursorExpr(C));
3101 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003102 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003103 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003104 }
3105
Douglas Gregor36897b02010-09-10 00:22:18 +00003106 if (clang_isStatement(C.kind)) {
3107 Stmt *S = getCursorStmt(C);
3108 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003109 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003110
3111 return createCXString("");
3112 }
3113
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003114 if (C.kind == CXCursor_MacroInstantiation)
3115 return createCXString(getCursorMacroInstantiation(C)->getName()
3116 ->getNameStart());
3117
Douglas Gregor572feb22010-03-18 18:04:21 +00003118 if (C.kind == CXCursor_MacroDefinition)
3119 return createCXString(getCursorMacroDefinition(C)->getName()
3120 ->getNameStart());
3121
Douglas Gregorecdcb882010-10-20 22:00:55 +00003122 if (C.kind == CXCursor_InclusionDirective)
3123 return createCXString(getCursorInclusionDirective(C)->getFileName());
3124
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003125 if (clang_isDeclaration(C.kind))
3126 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003127
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003128 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003129}
3130
Douglas Gregor358559d2010-10-02 22:49:11 +00003131CXString clang_getCursorDisplayName(CXCursor C) {
3132 if (!clang_isDeclaration(C.kind))
3133 return clang_getCursorSpelling(C);
3134
3135 Decl *D = getCursorDecl(C);
3136 if (!D)
3137 return createCXString("");
3138
3139 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3140 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3141 D = FunTmpl->getTemplatedDecl();
3142
3143 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3144 llvm::SmallString<64> Str;
3145 llvm::raw_svector_ostream OS(Str);
3146 OS << Function->getNameAsString();
3147 if (Function->getPrimaryTemplate())
3148 OS << "<>";
3149 OS << "(";
3150 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3151 if (I)
3152 OS << ", ";
3153 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3154 }
3155
3156 if (Function->isVariadic()) {
3157 if (Function->getNumParams())
3158 OS << ", ";
3159 OS << "...";
3160 }
3161 OS << ")";
3162 return createCXString(OS.str());
3163 }
3164
3165 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3166 llvm::SmallString<64> Str;
3167 llvm::raw_svector_ostream OS(Str);
3168 OS << ClassTemplate->getNameAsString();
3169 OS << "<";
3170 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3171 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3172 if (I)
3173 OS << ", ";
3174
3175 NamedDecl *Param = Params->getParam(I);
3176 if (Param->getIdentifier()) {
3177 OS << Param->getIdentifier()->getName();
3178 continue;
3179 }
3180
3181 // There is no parameter name, which makes this tricky. Try to come up
3182 // with something useful that isn't too long.
3183 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3184 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3185 else if (NonTypeTemplateParmDecl *NTTP
3186 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3187 OS << NTTP->getType().getAsString(Policy);
3188 else
3189 OS << "template<...> class";
3190 }
3191
3192 OS << ">";
3193 return createCXString(OS.str());
3194 }
3195
3196 if (ClassTemplateSpecializationDecl *ClassSpec
3197 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3198 // If the type was explicitly written, use that.
3199 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3200 return createCXString(TSInfo->getType().getAsString(Policy));
3201
3202 llvm::SmallString<64> Str;
3203 llvm::raw_svector_ostream OS(Str);
3204 OS << ClassSpec->getNameAsString();
3205 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003206 ClassSpec->getTemplateArgs().data(),
3207 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003208 Policy);
3209 return createCXString(OS.str());
3210 }
3211
3212 return clang_getCursorSpelling(C);
3213}
3214
Ted Kremeneke68fff62010-02-17 00:41:32 +00003215CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003216 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003217 case CXCursor_FunctionDecl:
3218 return createCXString("FunctionDecl");
3219 case CXCursor_TypedefDecl:
3220 return createCXString("TypedefDecl");
3221 case CXCursor_EnumDecl:
3222 return createCXString("EnumDecl");
3223 case CXCursor_EnumConstantDecl:
3224 return createCXString("EnumConstantDecl");
3225 case CXCursor_StructDecl:
3226 return createCXString("StructDecl");
3227 case CXCursor_UnionDecl:
3228 return createCXString("UnionDecl");
3229 case CXCursor_ClassDecl:
3230 return createCXString("ClassDecl");
3231 case CXCursor_FieldDecl:
3232 return createCXString("FieldDecl");
3233 case CXCursor_VarDecl:
3234 return createCXString("VarDecl");
3235 case CXCursor_ParmDecl:
3236 return createCXString("ParmDecl");
3237 case CXCursor_ObjCInterfaceDecl:
3238 return createCXString("ObjCInterfaceDecl");
3239 case CXCursor_ObjCCategoryDecl:
3240 return createCXString("ObjCCategoryDecl");
3241 case CXCursor_ObjCProtocolDecl:
3242 return createCXString("ObjCProtocolDecl");
3243 case CXCursor_ObjCPropertyDecl:
3244 return createCXString("ObjCPropertyDecl");
3245 case CXCursor_ObjCIvarDecl:
3246 return createCXString("ObjCIvarDecl");
3247 case CXCursor_ObjCInstanceMethodDecl:
3248 return createCXString("ObjCInstanceMethodDecl");
3249 case CXCursor_ObjCClassMethodDecl:
3250 return createCXString("ObjCClassMethodDecl");
3251 case CXCursor_ObjCImplementationDecl:
3252 return createCXString("ObjCImplementationDecl");
3253 case CXCursor_ObjCCategoryImplDecl:
3254 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003255 case CXCursor_CXXMethod:
3256 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003257 case CXCursor_UnexposedDecl:
3258 return createCXString("UnexposedDecl");
3259 case CXCursor_ObjCSuperClassRef:
3260 return createCXString("ObjCSuperClassRef");
3261 case CXCursor_ObjCProtocolRef:
3262 return createCXString("ObjCProtocolRef");
3263 case CXCursor_ObjCClassRef:
3264 return createCXString("ObjCClassRef");
3265 case CXCursor_TypeRef:
3266 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003267 case CXCursor_TemplateRef:
3268 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003269 case CXCursor_NamespaceRef:
3270 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003271 case CXCursor_MemberRef:
3272 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003273 case CXCursor_LabelRef:
3274 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003275 case CXCursor_OverloadedDeclRef:
3276 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003277 case CXCursor_UnexposedExpr:
3278 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003279 case CXCursor_BlockExpr:
3280 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003281 case CXCursor_DeclRefExpr:
3282 return createCXString("DeclRefExpr");
3283 case CXCursor_MemberRefExpr:
3284 return createCXString("MemberRefExpr");
3285 case CXCursor_CallExpr:
3286 return createCXString("CallExpr");
3287 case CXCursor_ObjCMessageExpr:
3288 return createCXString("ObjCMessageExpr");
3289 case CXCursor_UnexposedStmt:
3290 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003291 case CXCursor_LabelStmt:
3292 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003293 case CXCursor_InvalidFile:
3294 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003295 case CXCursor_InvalidCode:
3296 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003297 case CXCursor_NoDeclFound:
3298 return createCXString("NoDeclFound");
3299 case CXCursor_NotImplemented:
3300 return createCXString("NotImplemented");
3301 case CXCursor_TranslationUnit:
3302 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003303 case CXCursor_UnexposedAttr:
3304 return createCXString("UnexposedAttr");
3305 case CXCursor_IBActionAttr:
3306 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003307 case CXCursor_IBOutletAttr:
3308 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003309 case CXCursor_IBOutletCollectionAttr:
3310 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003311 case CXCursor_PreprocessingDirective:
3312 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003313 case CXCursor_MacroDefinition:
3314 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003315 case CXCursor_MacroInstantiation:
3316 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003317 case CXCursor_InclusionDirective:
3318 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003319 case CXCursor_Namespace:
3320 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003321 case CXCursor_LinkageSpec:
3322 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003323 case CXCursor_CXXBaseSpecifier:
3324 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003325 case CXCursor_Constructor:
3326 return createCXString("CXXConstructor");
3327 case CXCursor_Destructor:
3328 return createCXString("CXXDestructor");
3329 case CXCursor_ConversionFunction:
3330 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003331 case CXCursor_TemplateTypeParameter:
3332 return createCXString("TemplateTypeParameter");
3333 case CXCursor_NonTypeTemplateParameter:
3334 return createCXString("NonTypeTemplateParameter");
3335 case CXCursor_TemplateTemplateParameter:
3336 return createCXString("TemplateTemplateParameter");
3337 case CXCursor_FunctionTemplate:
3338 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003339 case CXCursor_ClassTemplate:
3340 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003341 case CXCursor_ClassTemplatePartialSpecialization:
3342 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003343 case CXCursor_NamespaceAlias:
3344 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003345 case CXCursor_UsingDirective:
3346 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003347 case CXCursor_UsingDeclaration:
3348 return createCXString("UsingDeclaration");
Richard Smith162e1c12011-04-15 14:24:37 +00003349 case CXCursor_TypeAliasDecl:
3350 return createCXString("TypeAliasDecl");
Steve Naroff89922f82009-08-31 00:59:03 +00003351 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003352
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003353 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003354 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003355}
Steve Naroff89922f82009-08-31 00:59:03 +00003356
Ted Kremeneke68fff62010-02-17 00:41:32 +00003357enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3358 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003359 CXClientData client_data) {
3360 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003361
3362 // If our current best cursor is the construction of a temporary object,
3363 // don't replace that cursor with a type reference, because we want
3364 // clang_getCursor() to point at the constructor.
3365 if (clang_isExpression(BestCursor->kind) &&
3366 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3367 cursor.kind == CXCursor_TypeRef)
3368 return CXChildVisit_Recurse;
3369
Douglas Gregor85fe1562010-12-10 07:23:11 +00003370 // Don't override a preprocessing cursor with another preprocessing
3371 // cursor; we want the outermost preprocessing cursor.
3372 if (clang_isPreprocessing(cursor.kind) &&
3373 clang_isPreprocessing(BestCursor->kind))
3374 return CXChildVisit_Recurse;
3375
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003376 *BestCursor = cursor;
3377 return CXChildVisit_Recurse;
3378}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003379
Douglas Gregorb9790342010-01-22 21:44:22 +00003380CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3381 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003382 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003383
Ted Kremeneka60ed472010-11-16 08:15:36 +00003384 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003385 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3386
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003387 // Translate the given source location to make it point at the beginning of
3388 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003389 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003390
3391 // Guard against an invalid SourceLocation, or we may assert in one
3392 // of the following calls.
3393 if (SLoc.isInvalid())
3394 return clang_getNullCursor();
3395
Douglas Gregor40749ee2010-11-03 00:35:38 +00003396 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003397 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3398 CXXUnit->getASTContext().getLangOptions());
3399
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003400 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3401 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003402 // FIXME: Would be great to have a "hint" cursor, then walk from that
3403 // hint cursor upward until we find a cursor whose source range encloses
3404 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003405 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3406 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00003407 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003408 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003409 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003410
3411 if (Logging) {
3412 CXFile SearchFile;
3413 unsigned SearchLine, SearchColumn;
3414 CXFile ResultFile;
3415 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003416 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3417 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003418 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3419
3420 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3421 0);
3422 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3423 &ResultColumn, 0);
3424 SearchFileName = clang_getFileName(SearchFile);
3425 ResultFileName = clang_getFileName(ResultFile);
3426 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003427 USR = clang_getCursorUSR(Result);
3428 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003429 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3430 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003431 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3432 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003433 clang_disposeString(SearchFileName);
3434 clang_disposeString(ResultFileName);
3435 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003436 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003437
3438 CXCursor Definition = clang_getCursorDefinition(Result);
3439 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3440 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3441 CXString DefinitionKindSpelling
3442 = clang_getCursorKindSpelling(Definition.kind);
3443 CXFile DefinitionFile;
3444 unsigned DefinitionLine, DefinitionColumn;
3445 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3446 &DefinitionLine, &DefinitionColumn, 0);
3447 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3448 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3449 clang_getCString(DefinitionKindSpelling),
3450 clang_getCString(DefinitionFileName),
3451 DefinitionLine, DefinitionColumn);
3452 clang_disposeString(DefinitionFileName);
3453 clang_disposeString(DefinitionKindSpelling);
3454 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003455 }
3456
Ted Kremeneke68fff62010-02-17 00:41:32 +00003457 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003458}
3459
Ted Kremenek73885552009-11-17 19:28:59 +00003460CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003461 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003462}
3463
3464unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003465 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003466}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003467
Douglas Gregor9ce55842010-11-20 00:09:34 +00003468unsigned clang_hashCursor(CXCursor C) {
3469 unsigned Index = 0;
3470 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3471 Index = 1;
3472
3473 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3474 std::make_pair(C.kind, C.data[Index]));
3475}
3476
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003477unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003478 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3479}
3480
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003481unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003482 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3483}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003484
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003485unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003486 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3487}
3488
Douglas Gregor97b98722010-01-19 23:20:36 +00003489unsigned clang_isExpression(enum CXCursorKind K) {
3490 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3491}
3492
3493unsigned clang_isStatement(enum CXCursorKind K) {
3494 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3495}
3496
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003497unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3498 return K == CXCursor_TranslationUnit;
3499}
3500
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003501unsigned clang_isPreprocessing(enum CXCursorKind K) {
3502 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3503}
3504
Ted Kremenekad6eff62010-03-08 21:17:29 +00003505unsigned clang_isUnexposed(enum CXCursorKind K) {
3506 switch (K) {
3507 case CXCursor_UnexposedDecl:
3508 case CXCursor_UnexposedExpr:
3509 case CXCursor_UnexposedStmt:
3510 case CXCursor_UnexposedAttr:
3511 return true;
3512 default:
3513 return false;
3514 }
3515}
3516
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003517CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003518 return C.kind;
3519}
3520
Douglas Gregor98258af2010-01-18 22:46:11 +00003521CXSourceLocation clang_getCursorLocation(CXCursor C) {
3522 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003523 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003524 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003525 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3526 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003527 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003528 }
3529
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003530 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003531 std::pair<ObjCProtocolDecl *, SourceLocation> P
3532 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003533 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003534 }
3535
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003536 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003537 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3538 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003539 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003540 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003541
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003542 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003543 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003544 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003545 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003546
3547 case CXCursor_TemplateRef: {
3548 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3549 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3550 }
3551
Douglas Gregor69319002010-08-31 23:48:11 +00003552 case CXCursor_NamespaceRef: {
3553 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3554 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3555 }
3556
Douglas Gregora67e03f2010-09-09 21:42:20 +00003557 case CXCursor_MemberRef: {
3558 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3559 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3560 }
3561
Ted Kremenek3064ef92010-08-27 21:34:58 +00003562 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003563 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3564 if (!BaseSpec)
3565 return clang_getNullLocation();
3566
3567 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3568 return cxloc::translateSourceLocation(getCursorContext(C),
3569 TSInfo->getTypeLoc().getBeginLoc());
3570
3571 return cxloc::translateSourceLocation(getCursorContext(C),
3572 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003573 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003574
Douglas Gregor36897b02010-09-10 00:22:18 +00003575 case CXCursor_LabelRef: {
3576 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3577 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3578 }
3579
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003580 case CXCursor_OverloadedDeclRef:
3581 return cxloc::translateSourceLocation(getCursorContext(C),
3582 getCursorOverloadedDeclRef(C).second);
3583
Douglas Gregorf46034a2010-01-18 23:41:10 +00003584 default:
3585 // FIXME: Need a way to enumerate all non-reference cases.
3586 llvm_unreachable("Missed a reference kind");
3587 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003588 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003589
3590 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003591 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003592 getLocationFromExpr(getCursorExpr(C)));
3593
Douglas Gregor36897b02010-09-10 00:22:18 +00003594 if (clang_isStatement(C.kind))
3595 return cxloc::translateSourceLocation(getCursorContext(C),
3596 getCursorStmt(C)->getLocStart());
3597
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003598 if (C.kind == CXCursor_PreprocessingDirective) {
3599 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3600 return cxloc::translateSourceLocation(getCursorContext(C), L);
3601 }
Douglas Gregor48072312010-03-18 15:23:44 +00003602
3603 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003604 SourceLocation L
3605 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003606 return cxloc::translateSourceLocation(getCursorContext(C), L);
3607 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003608
3609 if (C.kind == CXCursor_MacroDefinition) {
3610 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3611 return cxloc::translateSourceLocation(getCursorContext(C), L);
3612 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003613
3614 if (C.kind == CXCursor_InclusionDirective) {
3615 SourceLocation L
3616 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3617 return cxloc::translateSourceLocation(getCursorContext(C), L);
3618 }
3619
Ted Kremenek9a700d22010-05-12 06:16:13 +00003620 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003621 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003622
Douglas Gregorf46034a2010-01-18 23:41:10 +00003623 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003624 SourceLocation Loc = D->getLocation();
3625 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3626 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003627 // FIXME: Multiple variables declared in a single declaration
3628 // currently lack the information needed to correctly determine their
3629 // ranges when accounting for the type-specifier. We use context
3630 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3631 // and if so, whether it is the first decl.
3632 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3633 if (!cxcursor::isFirstInDeclGroup(C))
3634 Loc = VD->getLocation();
3635 }
3636
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003637 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003638}
Douglas Gregora7bde202010-01-19 00:34:46 +00003639
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003640} // end extern "C"
3641
3642static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003643 if (clang_isReference(C.kind)) {
3644 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003645 case CXCursor_ObjCSuperClassRef:
3646 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003647
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003648 case CXCursor_ObjCProtocolRef:
3649 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003650
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003651 case CXCursor_ObjCClassRef:
3652 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003653
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003654 case CXCursor_TypeRef:
3655 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003656
3657 case CXCursor_TemplateRef:
3658 return getCursorTemplateRef(C).second;
3659
Douglas Gregor69319002010-08-31 23:48:11 +00003660 case CXCursor_NamespaceRef:
3661 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003662
3663 case CXCursor_MemberRef:
3664 return getCursorMemberRef(C).second;
3665
Ted Kremenek3064ef92010-08-27 21:34:58 +00003666 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003667 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003668
Douglas Gregor36897b02010-09-10 00:22:18 +00003669 case CXCursor_LabelRef:
3670 return getCursorLabelRef(C).second;
3671
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003672 case CXCursor_OverloadedDeclRef:
3673 return getCursorOverloadedDeclRef(C).second;
3674
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003675 default:
3676 // FIXME: Need a way to enumerate all non-reference cases.
3677 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003678 }
3679 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003680
3681 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003682 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003683
3684 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003685 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003686
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003687 if (C.kind == CXCursor_PreprocessingDirective)
3688 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003689
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003690 if (C.kind == CXCursor_MacroInstantiation)
3691 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003692
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003693 if (C.kind == CXCursor_MacroDefinition)
3694 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003695
3696 if (C.kind == CXCursor_InclusionDirective)
3697 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3698
Ted Kremenek007a7c92010-11-01 23:26:51 +00003699 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3700 Decl *D = cxcursor::getCursorDecl(C);
3701 SourceRange R = D->getSourceRange();
3702 // FIXME: Multiple variables declared in a single declaration
3703 // currently lack the information needed to correctly determine their
3704 // ranges when accounting for the type-specifier. We use context
3705 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3706 // and if so, whether it is the first decl.
3707 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3708 if (!cxcursor::isFirstInDeclGroup(C))
3709 R.setBegin(VD->getLocation());
3710 }
3711 return R;
3712 }
Douglas Gregor66537982010-11-17 17:14:07 +00003713 return SourceRange();
3714}
3715
3716/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3717/// the decl-specifier-seq for declarations.
3718static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3719 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3720 Decl *D = cxcursor::getCursorDecl(C);
3721 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003722
Douglas Gregor2494dd02011-03-01 01:34:45 +00003723 // Adjust the start of the location for declarations preceded by
3724 // declaration specifiers.
3725 SourceLocation StartLoc;
3726 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3727 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3728 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3729 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3730 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3731 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3732 }
3733
3734 if (StartLoc.isValid() && R.getBegin().isValid() &&
3735 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3736 R.setBegin(StartLoc);
3737
3738 // FIXME: Multiple variables declared in a single declaration
3739 // currently lack the information needed to correctly determine their
3740 // ranges when accounting for the type-specifier. We use context
3741 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3742 // and if so, whether it is the first decl.
3743 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3744 if (!cxcursor::isFirstInDeclGroup(C))
3745 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003746 }
3747
3748 return R;
3749 }
3750
3751 return getRawCursorExtent(C);
3752}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003753
3754extern "C" {
3755
3756CXSourceRange clang_getCursorExtent(CXCursor C) {
3757 SourceRange R = getRawCursorExtent(C);
3758 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003759 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003760
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003761 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003762}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003763
3764CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003765 if (clang_isInvalid(C.kind))
3766 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003767
Ted Kremeneka60ed472010-11-16 08:15:36 +00003768 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003769 if (clang_isDeclaration(C.kind)) {
3770 Decl *D = getCursorDecl(C);
3771 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003772 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003773 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003774 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003775 if (ObjCForwardProtocolDecl *Protocols
3776 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003777 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003778 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3779 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3780 return MakeCXCursor(Property, tu);
3781
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003782 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003783 }
3784
Douglas Gregor97b98722010-01-19 23:20:36 +00003785 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003786 Expr *E = getCursorExpr(C);
3787 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003788 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003789 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003790
3791 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003792 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003793
Douglas Gregor97b98722010-01-19 23:20:36 +00003794 return clang_getNullCursor();
3795 }
3796
Douglas Gregor36897b02010-09-10 00:22:18 +00003797 if (clang_isStatement(C.kind)) {
3798 Stmt *S = getCursorStmt(C);
3799 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek37c2e962011-03-15 23:47:49 +00003800 if (LabelDecl *label = Goto->getLabel())
3801 if (LabelStmt *labelS = label->getStmt())
3802 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003803
3804 return clang_getNullCursor();
3805 }
3806
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003807 if (C.kind == CXCursor_MacroInstantiation) {
3808 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003809 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003810 }
3811
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003812 if (!clang_isReference(C.kind))
3813 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003814
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003815 switch (C.kind) {
3816 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003817 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003818
3819 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003820 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003821
3822 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003823 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003824
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003825 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003826 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003827
3828 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003829 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003830
Douglas Gregor69319002010-08-31 23:48:11 +00003831 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003832 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003833
Douglas Gregora67e03f2010-09-09 21:42:20 +00003834 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003835 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003836
Ted Kremenek3064ef92010-08-27 21:34:58 +00003837 case CXCursor_CXXBaseSpecifier: {
3838 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3839 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003840 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003841 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003842
Douglas Gregor36897b02010-09-10 00:22:18 +00003843 case CXCursor_LabelRef:
3844 // FIXME: We end up faking the "parent" declaration here because we
3845 // don't want to make CXCursor larger.
3846 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003847 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3848 .getTranslationUnitDecl(),
3849 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003850
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003851 case CXCursor_OverloadedDeclRef:
3852 return C;
3853
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003854 default:
3855 // We would prefer to enumerate all non-reference cursor kinds here.
3856 llvm_unreachable("Unhandled reference cursor kind");
3857 break;
3858 }
3859 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003860
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003861 return clang_getNullCursor();
3862}
3863
Douglas Gregorb6998662010-01-19 19:34:47 +00003864CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003865 if (clang_isInvalid(C.kind))
3866 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003867
Ted Kremeneka60ed472010-11-16 08:15:36 +00003868 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003869
Douglas Gregorb6998662010-01-19 19:34:47 +00003870 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003871 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003872 C = clang_getCursorReferenced(C);
3873 WasReference = true;
3874 }
3875
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003876 if (C.kind == CXCursor_MacroInstantiation)
3877 return clang_getCursorReferenced(C);
3878
Douglas Gregorb6998662010-01-19 19:34:47 +00003879 if (!clang_isDeclaration(C.kind))
3880 return clang_getNullCursor();
3881
3882 Decl *D = getCursorDecl(C);
3883 if (!D)
3884 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003885
Douglas Gregorb6998662010-01-19 19:34:47 +00003886 switch (D->getKind()) {
3887 // Declaration kinds that don't really separate the notions of
3888 // declaration and definition.
3889 case Decl::Namespace:
3890 case Decl::Typedef:
Richard Smith162e1c12011-04-15 14:24:37 +00003891 case Decl::TypeAlias:
Douglas Gregorb6998662010-01-19 19:34:47 +00003892 case Decl::TemplateTypeParm:
3893 case Decl::EnumConstant:
3894 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003895 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003896 case Decl::ObjCIvar:
3897 case Decl::ObjCAtDefsField:
3898 case Decl::ImplicitParam:
3899 case Decl::ParmVar:
3900 case Decl::NonTypeTemplateParm:
3901 case Decl::TemplateTemplateParm:
3902 case Decl::ObjCCategoryImpl:
3903 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003904 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003905 case Decl::LinkageSpec:
3906 case Decl::ObjCPropertyImpl:
3907 case Decl::FileScopeAsm:
3908 case Decl::StaticAssert:
3909 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003910 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003911 return C;
3912
3913 // Declaration kinds that don't make any sense here, but are
3914 // nonetheless harmless.
3915 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003916 break;
3917
3918 // Declaration kinds for which the definition is not resolvable.
3919 case Decl::UnresolvedUsingTypename:
3920 case Decl::UnresolvedUsingValue:
3921 break;
3922
3923 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003924 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003925 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003926
3927 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003928 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003929
3930 case Decl::Enum:
3931 case Decl::Record:
3932 case Decl::CXXRecord:
3933 case Decl::ClassTemplateSpecialization:
3934 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003935 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003936 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003937 return clang_getNullCursor();
3938
3939 case Decl::Function:
3940 case Decl::CXXMethod:
3941 case Decl::CXXConstructor:
3942 case Decl::CXXDestructor:
3943 case Decl::CXXConversion: {
3944 const FunctionDecl *Def = 0;
3945 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003946 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003947 return clang_getNullCursor();
3948 }
3949
3950 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003951 // Ask the variable if it has a definition.
3952 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003953 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003954 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003955 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003956
Douglas Gregorb6998662010-01-19 19:34:47 +00003957 case Decl::FunctionTemplate: {
3958 const FunctionDecl *Def = 0;
3959 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003960 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003961 return clang_getNullCursor();
3962 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003963
Douglas Gregorb6998662010-01-19 19:34:47 +00003964 case Decl::ClassTemplate: {
3965 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003966 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003967 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003968 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003969 return clang_getNullCursor();
3970 }
3971
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003972 case Decl::Using:
3973 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003974 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003975
3976 case Decl::UsingShadow:
3977 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003978 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003979 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003980
3981 case Decl::ObjCMethod: {
3982 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3983 if (Method->isThisDeclarationADefinition())
3984 return C;
3985
3986 // Dig out the method definition in the associated
3987 // @implementation, if we have it.
3988 // FIXME: The ASTs should make finding the definition easier.
3989 if (ObjCInterfaceDecl *Class
3990 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3991 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3992 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3993 Method->isInstanceMethod()))
3994 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003995 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003996
3997 return clang_getNullCursor();
3998 }
3999
4000 case Decl::ObjCCategory:
4001 if (ObjCCategoryImplDecl *Impl
4002 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004003 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004004 return clang_getNullCursor();
4005
4006 case Decl::ObjCProtocol:
4007 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
4008 return C;
4009 return clang_getNullCursor();
4010
4011 case Decl::ObjCInterface:
4012 // There are two notions of a "definition" for an Objective-C
4013 // class: the interface and its implementation. When we resolved a
4014 // reference to an Objective-C class, produce the @interface as
4015 // the definition; when we were provided with the interface,
4016 // produce the @implementation as the definition.
4017 if (WasReference) {
4018 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4019 return C;
4020 } else if (ObjCImplementationDecl *Impl
4021 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004022 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004023 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004024
Douglas Gregorb6998662010-01-19 19:34:47 +00004025 case Decl::ObjCProperty:
4026 // FIXME: We don't really know where to find the
4027 // ObjCPropertyImplDecls that implement this property.
4028 return clang_getNullCursor();
4029
4030 case Decl::ObjCCompatibleAlias:
4031 if (ObjCInterfaceDecl *Class
4032 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4033 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004034 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004035
Douglas Gregorb6998662010-01-19 19:34:47 +00004036 return clang_getNullCursor();
4037
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004038 case Decl::ObjCForwardProtocol:
4039 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004040 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004041
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004042 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004043 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004044 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004045
4046 case Decl::Friend:
4047 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004048 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004049 return clang_getNullCursor();
4050
4051 case Decl::FriendTemplate:
4052 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004053 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004054 return clang_getNullCursor();
4055 }
4056
4057 return clang_getNullCursor();
4058}
4059
4060unsigned clang_isCursorDefinition(CXCursor C) {
4061 if (!clang_isDeclaration(C.kind))
4062 return 0;
4063
4064 return clang_getCursorDefinition(C) == C;
4065}
4066
Douglas Gregor1a9d0502010-11-19 23:44:15 +00004067CXCursor clang_getCanonicalCursor(CXCursor C) {
4068 if (!clang_isDeclaration(C.kind))
4069 return C;
4070
4071 if (Decl *D = getCursorDecl(C))
4072 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4073
4074 return C;
4075}
4076
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004077unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004078 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004079 return 0;
4080
4081 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4082 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4083 return E->getNumDecls();
4084
4085 if (OverloadedTemplateStorage *S
4086 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4087 return S->size();
4088
4089 Decl *D = Storage.get<Decl*>();
4090 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00004091 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004092 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4093 return Classes->size();
4094 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4095 return Protocols->protocol_size();
4096
4097 return 0;
4098}
4099
4100CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004101 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004102 return clang_getNullCursor();
4103
4104 if (index >= clang_getNumOverloadedDecls(cursor))
4105 return clang_getNullCursor();
4106
Ted Kremeneka60ed472010-11-16 08:15:36 +00004107 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004108 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4109 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004110 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004111
4112 if (OverloadedTemplateStorage *S
4113 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004114 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004115
4116 Decl *D = Storage.get<Decl*>();
4117 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4118 // FIXME: This is, unfortunately, linear time.
4119 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4120 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004121 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004122 }
4123
4124 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004125 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004126
4127 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004128 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004129
4130 return clang_getNullCursor();
4131}
4132
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004133void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004134 const char **startBuf,
4135 const char **endBuf,
4136 unsigned *startLine,
4137 unsigned *startColumn,
4138 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004139 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004140 assert(getCursorDecl(C) && "CXCursor has null decl");
4141 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004142 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4143 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004144
Steve Naroff4ade6d62009-09-23 17:52:52 +00004145 SourceManager &SM = FD->getASTContext().getSourceManager();
4146 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4147 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4148 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4149 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4150 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4151 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4152}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004153
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004154void clang_enableStackTraces(void) {
4155 llvm::sys::PrintStackTraceOnErrorSignal();
4156}
4157
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004158void clang_executeOnThread(void (*fn)(void*), void *user_data,
4159 unsigned stack_size) {
4160 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4161}
4162
Ted Kremenekfb480492010-01-13 21:46:36 +00004163} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004164
Ted Kremenekfb480492010-01-13 21:46:36 +00004165//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004166// Token-based Operations.
4167//===----------------------------------------------------------------------===//
4168
4169/* CXToken layout:
4170 * int_data[0]: a CXTokenKind
4171 * int_data[1]: starting token location
4172 * int_data[2]: token length
4173 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004174 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004175 * otherwise unused.
4176 */
4177extern "C" {
4178
4179CXTokenKind clang_getTokenKind(CXToken CXTok) {
4180 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4181}
4182
4183CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4184 switch (clang_getTokenKind(CXTok)) {
4185 case CXToken_Identifier:
4186 case CXToken_Keyword:
4187 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004188 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4189 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004190
4191 case CXToken_Literal: {
4192 // We have stashed the starting pointer in the ptr_data field. Use it.
4193 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004194 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004195 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004196
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004197 case CXToken_Punctuation:
4198 case CXToken_Comment:
4199 break;
4200 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004201
4202 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004203 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004204 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004205 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004206 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004207
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004208 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4209 std::pair<FileID, unsigned> LocInfo
4210 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004211 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004212 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004213 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4214 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004215 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004216
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004217 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004218}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004219
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004220CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004221 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004222 if (!CXXUnit)
4223 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004224
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004225 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4226 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4227}
4228
4229CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004230 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004231 if (!CXXUnit)
4232 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004233
4234 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004235 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4236}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004237
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004238void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4239 CXToken **Tokens, unsigned *NumTokens) {
4240 if (Tokens)
4241 *Tokens = 0;
4242 if (NumTokens)
4243 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004244
Ted Kremeneka60ed472010-11-16 08:15:36 +00004245 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004246 if (!CXXUnit || !Tokens || !NumTokens)
4247 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004248
Douglas Gregorbdf60622010-03-05 21:16:25 +00004249 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4250
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004251 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004252 if (R.isInvalid())
4253 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004254
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004255 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4256 std::pair<FileID, unsigned> BeginLocInfo
4257 = SourceMgr.getDecomposedLoc(R.getBegin());
4258 std::pair<FileID, unsigned> EndLocInfo
4259 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004260
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004261 // Cannot tokenize across files.
4262 if (BeginLocInfo.first != EndLocInfo.first)
4263 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004264
4265 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004266 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004267 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004268 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004269 if (Invalid)
4270 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004271
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004272 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4273 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004274 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004275 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004276
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004277 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004278 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004279 llvm::SmallVector<CXToken, 32> CXTokens;
4280 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004281 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004282 do {
4283 // Lex the next token
4284 Lex.LexFromRawLexer(Tok);
4285 if (Tok.is(tok::eof))
4286 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004287
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004288 // Initialize the CXToken.
4289 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004290
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004291 // - Common fields
4292 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4293 CXTok.int_data[2] = Tok.getLength();
4294 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004295
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004296 // - Kind-specific fields
4297 if (Tok.isLiteral()) {
4298 CXTok.int_data[0] = CXToken_Literal;
4299 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004300 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004301 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004302 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004303 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004304
David Chisnall096428b2010-10-13 21:44:48 +00004305 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004306 CXTok.int_data[0] = CXToken_Keyword;
4307 }
4308 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004309 CXTok.int_data[0] = Tok.is(tok::identifier)
4310 ? CXToken_Identifier
4311 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004312 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004313 CXTok.ptr_data = II;
4314 } else if (Tok.is(tok::comment)) {
4315 CXTok.int_data[0] = CXToken_Comment;
4316 CXTok.ptr_data = 0;
4317 } else {
4318 CXTok.int_data[0] = CXToken_Punctuation;
4319 CXTok.ptr_data = 0;
4320 }
4321 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004322 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004323 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004324
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004325 if (CXTokens.empty())
4326 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004327
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004328 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4329 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4330 *NumTokens = CXTokens.size();
4331}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004332
Ted Kremenek6db61092010-05-05 00:55:15 +00004333void clang_disposeTokens(CXTranslationUnit TU,
4334 CXToken *Tokens, unsigned NumTokens) {
4335 free(Tokens);
4336}
4337
4338} // end: extern "C"
4339
4340//===----------------------------------------------------------------------===//
4341// Token annotation APIs.
4342//===----------------------------------------------------------------------===//
4343
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004344typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004345static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4346 CXCursor parent,
4347 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004348namespace {
4349class AnnotateTokensWorker {
4350 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004351 CXToken *Tokens;
4352 CXCursor *Cursors;
4353 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004354 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004355 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004356 CursorVisitor AnnotateVis;
4357 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004358 bool HasContextSensitiveKeywords;
4359
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004360 bool MoreTokens() const { return TokIdx < NumTokens; }
4361 unsigned NextToken() const { return TokIdx; }
4362 void AdvanceToken() { ++TokIdx; }
4363 SourceLocation GetTokenLoc(unsigned tokI) {
4364 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4365 }
4366
Ted Kremenek6db61092010-05-05 00:55:15 +00004367public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004368 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004369 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004370 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004371 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004372 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004373 AnnotateVis(tu,
4374 AnnotateTokensVisitor, this,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00004375 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004376 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4377 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004378
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004379 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004380 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004381 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004382 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004383 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004384 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004385
4386 /// \brief Determine whether the annotator saw any cursors that have
4387 /// context-sensitive keywords.
4388 bool hasContextSensitiveKeywords() const {
4389 return HasContextSensitiveKeywords;
4390 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004391};
4392}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004393
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004394void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4395 // Walk the AST within the region of interest, annotating tokens
4396 // along the way.
4397 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004398
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004399 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4400 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004401 if (Pos != Annotated.end() &&
4402 (clang_isInvalid(Cursors[I].kind) ||
4403 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004404 Cursors[I] = Pos->second;
4405 }
4406
4407 // Finish up annotating any tokens left.
4408 if (!MoreTokens())
4409 return;
4410
4411 const CXCursor &C = clang_getNullCursor();
4412 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4413 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4414 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004415 }
4416}
4417
Ted Kremenek6db61092010-05-05 00:55:15 +00004418enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004419AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004420 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004421 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004422 if (cursorRange.isInvalid())
4423 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004424
4425 if (!HasContextSensitiveKeywords) {
4426 // Objective-C properties can have context-sensitive keywords.
4427 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4428 if (ObjCPropertyDecl *Property
4429 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4430 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4431 }
4432 // Objective-C methods can have context-sensitive keywords.
4433 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4434 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4435 if (ObjCMethodDecl *Method
4436 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4437 if (Method->getObjCDeclQualifier())
4438 HasContextSensitiveKeywords = true;
4439 else {
4440 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4441 PEnd = Method->param_end();
4442 P != PEnd; ++P) {
4443 if ((*P)->getObjCDeclQualifier()) {
4444 HasContextSensitiveKeywords = true;
4445 break;
4446 }
4447 }
4448 }
4449 }
4450 }
4451 // C++ methods can have context-sensitive keywords.
4452 else if (cursor.kind == CXCursor_CXXMethod) {
4453 if (CXXMethodDecl *Method
4454 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4455 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4456 HasContextSensitiveKeywords = true;
4457 }
4458 }
4459 // C++ classes can have context-sensitive keywords.
4460 else if (cursor.kind == CXCursor_StructDecl ||
4461 cursor.kind == CXCursor_ClassDecl ||
4462 cursor.kind == CXCursor_ClassTemplate ||
4463 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4464 if (Decl *D = getCursorDecl(cursor))
4465 if (D->hasAttr<FinalAttr>())
4466 HasContextSensitiveKeywords = true;
4467 }
4468 }
4469
Douglas Gregor4419b672010-10-21 06:10:04 +00004470 if (clang_isPreprocessing(cursor.kind)) {
4471 // For macro instantiations, just note where the beginning of the macro
4472 // instantiation occurs.
4473 if (cursor.kind == CXCursor_MacroInstantiation) {
4474 Annotated[Loc.int_data] = cursor;
4475 return CXChildVisit_Recurse;
4476 }
4477
Douglas Gregor4419b672010-10-21 06:10:04 +00004478 // Items in the preprocessing record are kept separate from items in
4479 // declarations, so we keep a separate token index.
4480 unsigned SavedTokIdx = TokIdx;
4481 TokIdx = PreprocessingTokIdx;
4482
4483 // Skip tokens up until we catch up to the beginning of the preprocessing
4484 // entry.
4485 while (MoreTokens()) {
4486 const unsigned I = NextToken();
4487 SourceLocation TokLoc = GetTokenLoc(I);
4488 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4489 case RangeBefore:
4490 AdvanceToken();
4491 continue;
4492 case RangeAfter:
4493 case RangeOverlap:
4494 break;
4495 }
4496 break;
4497 }
4498
4499 // Look at all of the tokens within this range.
4500 while (MoreTokens()) {
4501 const unsigned I = NextToken();
4502 SourceLocation TokLoc = GetTokenLoc(I);
4503 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4504 case RangeBefore:
4505 assert(0 && "Infeasible");
4506 case RangeAfter:
4507 break;
4508 case RangeOverlap:
4509 Cursors[I] = cursor;
4510 AdvanceToken();
4511 continue;
4512 }
4513 break;
4514 }
4515
4516 // Save the preprocessing token index; restore the non-preprocessing
4517 // token index.
4518 PreprocessingTokIdx = TokIdx;
4519 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004520 return CXChildVisit_Recurse;
4521 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004522
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004523 if (cursorRange.isInvalid())
4524 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004525
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004526 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4527
Ted Kremeneka333c662010-05-12 05:29:33 +00004528 // Adjust the annotated range based specific declarations.
4529 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4530 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004531 Decl *D = cxcursor::getCursorDecl(cursor);
4532 // Don't visit synthesized ObjC methods, since they have no syntatic
4533 // representation in the source.
4534 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4535 if (MD->isSynthesized())
4536 return CXChildVisit_Continue;
4537 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004538
4539 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004540 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004541 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4542 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4543 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4544 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4545 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004546 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004547
4548 if (StartLoc.isValid() && L.isValid() &&
4549 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4550 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004551 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004552
Ted Kremenek3f404602010-08-14 01:14:06 +00004553 // If the location of the cursor occurs within a macro instantiation, record
4554 // the spelling location of the cursor in our annotation map. We can then
4555 // paper over the token labelings during a post-processing step to try and
4556 // get cursor mappings for tokens that are the *arguments* of a macro
4557 // instantiation.
4558 if (L.isMacroID()) {
4559 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4560 // Only invalidate the old annotation if it isn't part of a preprocessing
4561 // directive. Here we assume that the default construction of CXCursor
4562 // results in CXCursor.kind being an initialized value (i.e., 0). If
4563 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004564
Ted Kremenek3f404602010-08-14 01:14:06 +00004565 CXCursor &oldC = Annotated[rawEncoding];
4566 if (!clang_isPreprocessing(oldC.kind))
4567 oldC = cursor;
4568 }
4569
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004570 const enum CXCursorKind K = clang_getCursorKind(parent);
4571 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004572 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4573 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004574
4575 while (MoreTokens()) {
4576 const unsigned I = NextToken();
4577 SourceLocation TokLoc = GetTokenLoc(I);
4578 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4579 case RangeBefore:
4580 Cursors[I] = updateC;
4581 AdvanceToken();
4582 continue;
4583 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004584 case RangeOverlap:
4585 break;
4586 }
4587 break;
4588 }
4589
4590 // Visit children to get their cursor information.
4591 const unsigned BeforeChildren = NextToken();
4592 VisitChildren(cursor);
4593 const unsigned AfterChildren = NextToken();
4594
4595 // Adjust 'Last' to the last token within the extent of the cursor.
4596 while (MoreTokens()) {
4597 const unsigned I = NextToken();
4598 SourceLocation TokLoc = GetTokenLoc(I);
4599 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4600 case RangeBefore:
4601 assert(0 && "Infeasible");
4602 case RangeAfter:
4603 break;
4604 case RangeOverlap:
4605 Cursors[I] = updateC;
4606 AdvanceToken();
4607 continue;
4608 }
4609 break;
4610 }
4611 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004612
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004613 // Scan the tokens that are at the beginning of the cursor, but are not
4614 // capture by the child cursors.
4615
4616 // For AST elements within macros, rely on a post-annotate pass to
4617 // to correctly annotate the tokens with cursors. Otherwise we can
4618 // get confusing results of having tokens that map to cursors that really
4619 // are expanded by an instantiation.
4620 if (L.isMacroID())
4621 cursor = clang_getNullCursor();
4622
4623 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4624 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4625 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004626
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004627 Cursors[I] = cursor;
4628 }
4629 // Scan the tokens that are at the end of the cursor, but are not captured
4630 // but the child cursors.
4631 for (unsigned I = AfterChildren; I != Last; ++I)
4632 Cursors[I] = cursor;
4633
4634 TokIdx = Last;
4635 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004636}
4637
Ted Kremenek6db61092010-05-05 00:55:15 +00004638static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4639 CXCursor parent,
4640 CXClientData client_data) {
4641 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4642}
4643
Ted Kremenek6628a612011-03-18 22:51:30 +00004644namespace {
4645 struct clang_annotateTokens_Data {
4646 CXTranslationUnit TU;
4647 ASTUnit *CXXUnit;
4648 CXToken *Tokens;
4649 unsigned NumTokens;
4650 CXCursor *Cursors;
4651 };
4652}
4653
Ted Kremenekab979612010-11-11 08:05:23 +00004654// This gets run a separate thread to avoid stack blowout.
Ted Kremenek6628a612011-03-18 22:51:30 +00004655static void clang_annotateTokensImpl(void *UserData) {
4656 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4657 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4658 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4659 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4660 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4661
4662 // Determine the region of interest, which contains all of the tokens.
4663 SourceRange RegionOfInterest;
4664 RegionOfInterest.setBegin(
4665 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4666 RegionOfInterest.setEnd(
4667 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4668 Tokens[NumTokens-1])));
4669
4670 // A mapping from the source locations found when re-lexing or traversing the
4671 // region of interest to the corresponding cursors.
4672 AnnotateTokensData Annotated;
4673
4674 // Relex the tokens within the source range to look for preprocessing
4675 // directives.
4676 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4677 std::pair<FileID, unsigned> BeginLocInfo
4678 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4679 std::pair<FileID, unsigned> EndLocInfo
4680 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4681
4682 llvm::StringRef Buffer;
4683 bool Invalid = false;
4684 if (BeginLocInfo.first == EndLocInfo.first &&
4685 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4686 !Invalid) {
4687 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4688 CXXUnit->getASTContext().getLangOptions(),
4689 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4690 Buffer.end());
4691 Lex.SetCommentRetentionState(true);
4692
4693 // Lex tokens in raw mode until we hit the end of the range, to avoid
4694 // entering #includes or expanding macros.
4695 while (true) {
4696 Token Tok;
4697 Lex.LexFromRawLexer(Tok);
4698
4699 reprocess:
4700 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4701 // We have found a preprocessing directive. Gobble it up so that we
4702 // don't see it while preprocessing these tokens later, but keep track
4703 // of all of the token locations inside this preprocessing directive so
4704 // that we can annotate them appropriately.
4705 //
4706 // FIXME: Some simple tests here could identify macro definitions and
4707 // #undefs, to provide specific cursor kinds for those.
4708 llvm::SmallVector<SourceLocation, 32> Locations;
4709 do {
4710 Locations.push_back(Tok.getLocation());
4711 Lex.LexFromRawLexer(Tok);
4712 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4713
4714 using namespace cxcursor;
4715 CXCursor Cursor
4716 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4717 Locations.back()),
4718 TU);
4719 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4720 Annotated[Locations[I].getRawEncoding()] = Cursor;
4721 }
4722
4723 if (Tok.isAtStartOfLine())
4724 goto reprocess;
4725
4726 continue;
4727 }
4728
4729 if (Tok.is(tok::eof))
4730 break;
4731 }
4732 }
4733
4734 // Annotate all of the source locations in the region of interest that map to
4735 // a specific cursor.
4736 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4737 TU, RegionOfInterest);
4738
4739 // FIXME: We use a ridiculous stack size here because the data-recursion
4740 // algorithm uses a large stack frame than the non-data recursive version,
4741 // and AnnotationTokensWorker currently transforms the data-recursion
4742 // algorithm back into a traditional recursion by explicitly calling
4743 // VisitChildren(). We will need to remove this explicit recursive call.
4744 W.AnnotateTokens();
4745
4746 // If we ran into any entities that involve context-sensitive keywords,
4747 // take another pass through the tokens to mark them as such.
4748 if (W.hasContextSensitiveKeywords()) {
4749 for (unsigned I = 0; I != NumTokens; ++I) {
4750 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4751 continue;
4752
4753 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4754 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4755 if (ObjCPropertyDecl *Property
4756 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4757 if (Property->getPropertyAttributesAsWritten() != 0 &&
4758 llvm::StringSwitch<bool>(II->getName())
4759 .Case("readonly", true)
4760 .Case("assign", true)
4761 .Case("readwrite", true)
4762 .Case("retain", true)
4763 .Case("copy", true)
4764 .Case("nonatomic", true)
4765 .Case("atomic", true)
4766 .Case("getter", true)
4767 .Case("setter", true)
4768 .Default(false))
4769 Tokens[I].int_data[0] = CXToken_Keyword;
4770 }
4771 continue;
4772 }
4773
4774 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4775 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4776 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4777 if (llvm::StringSwitch<bool>(II->getName())
4778 .Case("in", true)
4779 .Case("out", true)
4780 .Case("inout", true)
4781 .Case("oneway", true)
4782 .Case("bycopy", true)
4783 .Case("byref", true)
4784 .Default(false))
4785 Tokens[I].int_data[0] = CXToken_Keyword;
4786 continue;
4787 }
4788
4789 if (Cursors[I].kind == CXCursor_CXXMethod) {
4790 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4791 if (CXXMethodDecl *Method
4792 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4793 if ((Method->hasAttr<FinalAttr>() ||
4794 Method->hasAttr<OverrideAttr>()) &&
4795 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4796 llvm::StringSwitch<bool>(II->getName())
4797 .Case("final", true)
4798 .Case("override", true)
4799 .Default(false))
4800 Tokens[I].int_data[0] = CXToken_Keyword;
4801 }
4802 continue;
4803 }
4804
4805 if (Cursors[I].kind == CXCursor_ClassDecl ||
4806 Cursors[I].kind == CXCursor_StructDecl ||
4807 Cursors[I].kind == CXCursor_ClassTemplate) {
4808 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4809 if (II->getName() == "final") {
4810 // We have to be careful with 'final', since it could be the name
4811 // of a member class rather than the context-sensitive keyword.
4812 // So, check whether the cursor associated with this
4813 Decl *D = getCursorDecl(Cursors[I]);
4814 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4815 if ((Record->hasAttr<FinalAttr>()) &&
4816 Record->getIdentifier() != II)
4817 Tokens[I].int_data[0] = CXToken_Keyword;
4818 } else if (ClassTemplateDecl *ClassTemplate
4819 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4820 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4821 if ((Record->hasAttr<FinalAttr>()) &&
4822 Record->getIdentifier() != II)
4823 Tokens[I].int_data[0] = CXToken_Keyword;
4824 }
4825 }
4826 continue;
4827 }
4828 }
4829 }
Ted Kremenekab979612010-11-11 08:05:23 +00004830}
4831
Ted Kremenek6db61092010-05-05 00:55:15 +00004832extern "C" {
4833
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004834void clang_annotateTokens(CXTranslationUnit TU,
4835 CXToken *Tokens, unsigned NumTokens,
4836 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004837
4838 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004839 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004840
Douglas Gregor4419b672010-10-21 06:10:04 +00004841 // Any token we don't specifically annotate will have a NULL cursor.
4842 CXCursor C = clang_getNullCursor();
4843 for (unsigned I = 0; I != NumTokens; ++I)
4844 Cursors[I] = C;
4845
Ted Kremeneka60ed472010-11-16 08:15:36 +00004846 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004847 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004848 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004849
Douglas Gregorbdf60622010-03-05 21:16:25 +00004850 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek6628a612011-03-18 22:51:30 +00004851
4852 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekab979612010-11-11 08:05:23 +00004853 llvm::CrashRecoveryContext CRC;
Ted Kremenek6628a612011-03-18 22:51:30 +00004854 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004855 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004856 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4857 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004858}
Ted Kremenek6628a612011-03-18 22:51:30 +00004859
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004860} // end: extern "C"
4861
4862//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004863// Operations for querying linkage of a cursor.
4864//===----------------------------------------------------------------------===//
4865
4866extern "C" {
4867CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004868 if (!clang_isDeclaration(cursor.kind))
4869 return CXLinkage_Invalid;
4870
Ted Kremenek16b42592010-03-03 06:36:57 +00004871 Decl *D = cxcursor::getCursorDecl(cursor);
4872 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4873 switch (ND->getLinkage()) {
4874 case NoLinkage: return CXLinkage_NoLinkage;
4875 case InternalLinkage: return CXLinkage_Internal;
4876 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4877 case ExternalLinkage: return CXLinkage_External;
4878 };
4879
4880 return CXLinkage_Invalid;
4881}
4882} // end: extern "C"
4883
4884//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004885// Operations for querying language of a cursor.
4886//===----------------------------------------------------------------------===//
4887
4888static CXLanguageKind getDeclLanguage(const Decl *D) {
4889 switch (D->getKind()) {
4890 default:
4891 break;
4892 case Decl::ImplicitParam:
4893 case Decl::ObjCAtDefsField:
4894 case Decl::ObjCCategory:
4895 case Decl::ObjCCategoryImpl:
4896 case Decl::ObjCClass:
4897 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004898 case Decl::ObjCForwardProtocol:
4899 case Decl::ObjCImplementation:
4900 case Decl::ObjCInterface:
4901 case Decl::ObjCIvar:
4902 case Decl::ObjCMethod:
4903 case Decl::ObjCProperty:
4904 case Decl::ObjCPropertyImpl:
4905 case Decl::ObjCProtocol:
4906 return CXLanguage_ObjC;
4907 case Decl::CXXConstructor:
4908 case Decl::CXXConversion:
4909 case Decl::CXXDestructor:
4910 case Decl::CXXMethod:
4911 case Decl::CXXRecord:
4912 case Decl::ClassTemplate:
4913 case Decl::ClassTemplatePartialSpecialization:
4914 case Decl::ClassTemplateSpecialization:
4915 case Decl::Friend:
4916 case Decl::FriendTemplate:
4917 case Decl::FunctionTemplate:
4918 case Decl::LinkageSpec:
4919 case Decl::Namespace:
4920 case Decl::NamespaceAlias:
4921 case Decl::NonTypeTemplateParm:
4922 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004923 case Decl::TemplateTemplateParm:
4924 case Decl::TemplateTypeParm:
4925 case Decl::UnresolvedUsingTypename:
4926 case Decl::UnresolvedUsingValue:
4927 case Decl::Using:
4928 case Decl::UsingDirective:
4929 case Decl::UsingShadow:
4930 return CXLanguage_CPlusPlus;
4931 }
4932
4933 return CXLanguage_C;
4934}
4935
4936extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004937
4938enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4939 if (clang_isDeclaration(cursor.kind))
4940 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004941 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregor58ddb602010-08-23 23:00:57 +00004942 return CXAvailability_Available;
4943
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004944 switch (D->getAvailability()) {
4945 case AR_Available:
4946 case AR_NotYetIntroduced:
4947 return CXAvailability_Available;
4948
4949 case AR_Deprecated:
Douglas Gregor58ddb602010-08-23 23:00:57 +00004950 return CXAvailability_Deprecated;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004951
4952 case AR_Unavailable:
4953 return CXAvailability_NotAvailable;
4954 }
Douglas Gregor58ddb602010-08-23 23:00:57 +00004955 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004956
Douglas Gregor58ddb602010-08-23 23:00:57 +00004957 return CXAvailability_Available;
4958}
4959
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004960CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4961 if (clang_isDeclaration(cursor.kind))
4962 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4963
4964 return CXLanguage_Invalid;
4965}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004966
4967 /// \brief If the given cursor is the "templated" declaration
4968 /// descibing a class or function template, return the class or
4969 /// function template.
4970static Decl *maybeGetTemplateCursor(Decl *D) {
4971 if (!D)
4972 return 0;
4973
4974 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4975 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4976 return FunTmpl;
4977
4978 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4979 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4980 return ClassTmpl;
4981
4982 return D;
4983}
4984
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004985CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4986 if (clang_isDeclaration(cursor.kind)) {
4987 if (Decl *D = getCursorDecl(cursor)) {
4988 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004989 if (!DC)
4990 return clang_getNullCursor();
4991
4992 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4993 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004994 }
4995 }
4996
4997 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4998 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004999 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005000 }
5001
5002 return clang_getNullCursor();
5003}
5004
5005CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5006 if (clang_isDeclaration(cursor.kind)) {
5007 if (Decl *D = getCursorDecl(cursor)) {
5008 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00005009 if (!DC)
5010 return clang_getNullCursor();
5011
5012 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5013 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005014 }
5015 }
5016
5017 // FIXME: Note that we can't easily compute the lexical context of a
5018 // statement or expression, so we return nothing.
5019 return clang_getNullCursor();
5020}
5021
Douglas Gregor9f592342010-10-01 20:25:15 +00005022static void CollectOverriddenMethods(DeclContext *Ctx,
5023 ObjCMethodDecl *Method,
5024 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5025 if (!Ctx)
5026 return;
5027
5028 // If we have a class or category implementation, jump straight to the
5029 // interface.
5030 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5031 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5032
5033 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5034 if (!Container)
5035 return;
5036
5037 // Check whether we have a matching method at this level.
5038 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5039 Method->isInstanceMethod()))
5040 if (Method != Overridden) {
5041 // We found an override at this level; there is no need to look
5042 // into other protocols or categories.
5043 Methods.push_back(Overridden);
5044 return;
5045 }
5046
5047 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5048 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5049 PEnd = Protocol->protocol_end();
5050 P != PEnd; ++P)
5051 CollectOverriddenMethods(*P, Method, Methods);
5052 }
5053
5054 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5055 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5056 PEnd = Category->protocol_end();
5057 P != PEnd; ++P)
5058 CollectOverriddenMethods(*P, Method, Methods);
5059 }
5060
5061 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5062 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5063 PEnd = Interface->protocol_end();
5064 P != PEnd; ++P)
5065 CollectOverriddenMethods(*P, Method, Methods);
5066
5067 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5068 Category; Category = Category->getNextClassCategory())
5069 CollectOverriddenMethods(Category, Method, Methods);
5070
5071 // We only look into the superclass if we haven't found anything yet.
5072 if (Methods.empty())
5073 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5074 return CollectOverriddenMethods(Super, Method, Methods);
5075 }
5076}
5077
5078void clang_getOverriddenCursors(CXCursor cursor,
5079 CXCursor **overridden,
5080 unsigned *num_overridden) {
5081 if (overridden)
5082 *overridden = 0;
5083 if (num_overridden)
5084 *num_overridden = 0;
5085 if (!overridden || !num_overridden)
5086 return;
5087
5088 if (!clang_isDeclaration(cursor.kind))
5089 return;
5090
5091 Decl *D = getCursorDecl(cursor);
5092 if (!D)
5093 return;
5094
5095 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00005096 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00005097 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5098 *num_overridden = CXXMethod->size_overridden_methods();
5099 if (!*num_overridden)
5100 return;
5101
5102 *overridden = new CXCursor [*num_overridden];
5103 unsigned I = 0;
5104 for (CXXMethodDecl::method_iterator
5105 M = CXXMethod->begin_overridden_methods(),
5106 MEnd = CXXMethod->end_overridden_methods();
5107 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005108 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005109 return;
5110 }
5111
5112 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5113 if (!Method)
5114 return;
5115
5116 // Handle Objective-C methods.
5117 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5118 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5119
5120 if (Methods.empty())
5121 return;
5122
5123 *num_overridden = Methods.size();
5124 *overridden = new CXCursor [Methods.size()];
5125 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005126 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005127}
5128
5129void clang_disposeOverriddenCursors(CXCursor *overridden) {
5130 delete [] overridden;
5131}
5132
Douglas Gregorecdcb882010-10-20 22:00:55 +00005133CXFile clang_getIncludedFile(CXCursor cursor) {
5134 if (cursor.kind != CXCursor_InclusionDirective)
5135 return 0;
5136
5137 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5138 return (void *)ID->getFile();
5139}
5140
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005141} // end: extern "C"
5142
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005143
5144//===----------------------------------------------------------------------===//
5145// C++ AST instrospection.
5146//===----------------------------------------------------------------------===//
5147
5148extern "C" {
5149unsigned clang_CXXMethod_isStatic(CXCursor C) {
5150 if (!clang_isDeclaration(C.kind))
5151 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005152
5153 CXXMethodDecl *Method = 0;
5154 Decl *D = cxcursor::getCursorDecl(C);
5155 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5156 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5157 else
5158 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5159 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005160}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005161
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005162} // end: extern "C"
5163
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005164//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005165// Attribute introspection.
5166//===----------------------------------------------------------------------===//
5167
5168extern "C" {
5169CXType clang_getIBOutletCollectionType(CXCursor C) {
5170 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005171 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005172
5173 IBOutletCollectionAttr *A =
5174 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5175
Douglas Gregor841b2382011-03-06 18:55:32 +00005176 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005177}
5178} // end: extern "C"
5179
5180//===----------------------------------------------------------------------===//
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005181// Inspecting memory usage.
5182//===----------------------------------------------------------------------===//
5183
Ted Kremenekf7870022011-04-20 16:41:07 +00005184typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005185
Ted Kremenekf7870022011-04-20 16:41:07 +00005186static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
5187 enum CXTUResourceUsageKind k,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005188 double amount) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005189 CXTUResourceUsageEntry entry = { k, amount };
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005190 entries.push_back(entry);
5191}
5192
5193extern "C" {
5194
Ted Kremenekf7870022011-04-20 16:41:07 +00005195const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005196 const char *str = "";
5197 switch (kind) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005198 case CXTUResourceUsage_AST:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005199 str = "ASTContext: expressions, declarations, and types";
5200 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005201 case CXTUResourceUsage_Identifiers:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005202 str = "ASTContext: identifiers";
5203 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005204 case CXTUResourceUsage_Selectors:
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005205 str = "ASTContext: selectors";
Ted Kremeneke294ab72011-04-19 04:36:17 +00005206 break;
Ted Kremenekf7870022011-04-20 16:41:07 +00005207 case CXTUResourceUsage_GlobalCompletionResults:
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005208 str = "Code completion: cached global results";
Ted Kremeneke294ab72011-04-19 04:36:17 +00005209 break;
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005210 }
5211 return str;
5212}
5213
Ted Kremenekf7870022011-04-20 16:41:07 +00005214CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005215 if (!TU) {
Ted Kremenekf7870022011-04-20 16:41:07 +00005216 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005217 return usage;
5218 }
5219
5220 ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
5221 llvm::OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
5222 ASTContext &astContext = astUnit->getASTContext();
5223
5224 // How much memory is used by AST nodes and types?
Ted Kremenekf7870022011-04-20 16:41:07 +00005225 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005226 (unsigned long) astContext.getTotalAllocatedMemory());
5227
5228 // How much memory is used by identifiers?
Ted Kremenekf7870022011-04-20 16:41:07 +00005229 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005230 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
5231
5232 // How much memory is used for selectors?
Ted Kremenekf7870022011-04-20 16:41:07 +00005233 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005234 (unsigned long) astContext.Selectors.getTotalMemory());
5235
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005236 // How much memory is used for caching global code completion results?
5237 unsigned long completionBytes = 0;
5238 if (GlobalCodeCompletionAllocator *completionAllocator =
5239 astUnit->getCachedCompletionAllocator().getPtr()) {
5240 completionBytes = completionAllocator-> getTotalMemory();
5241 }
Ted Kremenekf7870022011-04-20 16:41:07 +00005242 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_GlobalCompletionResults,
Ted Kremenek4e6a3f72011-04-18 23:42:53 +00005243 completionBytes);
5244
5245
Ted Kremenekf7870022011-04-20 16:41:07 +00005246 CXTUResourceUsage usage = { (void*) entries.get(),
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005247 (unsigned) entries->size(),
5248 entries->size() ? &(*entries)[0] : 0 };
5249 entries.take();
5250 return usage;
5251}
5252
Ted Kremenekf7870022011-04-20 16:41:07 +00005253void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005254 if (usage.data)
5255 delete (MemUsageEntries*) usage.data;
5256}
5257
5258} // end extern "C"
5259
5260//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005261// Misc. utility functions.
5262//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005263
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005264/// Default to using an 8 MB stack size on "safety" threads.
5265static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005266
5267namespace clang {
5268
5269bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005270 void (*Fn)(void*), void *UserData,
5271 unsigned Size) {
5272 if (!Size)
5273 Size = GetSafetyThreadStackSize();
5274 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005275 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5276 return CRC.RunSafely(Fn, UserData);
5277}
5278
5279unsigned GetSafetyThreadStackSize() {
5280 return SafetyStackThreadSize;
5281}
5282
5283void SetSafetyThreadStackSize(unsigned Value) {
5284 SafetyStackThreadSize = Value;
5285}
5286
5287}
5288
Ted Kremenek04bb7162010-01-22 22:44:15 +00005289extern "C" {
5290
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005291CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005292 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005293}
5294
5295} // end: extern "C"
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005296