blob: 2ac57bf2080cd7a61758b82bfa26b96af5e70874 [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);
2776 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID);
2777 if (!sloc.isFile()) {
2778 createNullLocation(file, line, column, offset);
2779 return;
2780 }
2781
Douglas Gregor1db19de2010-01-19 21:36:55 +00002782 if (file)
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002783 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002784 if (line)
2785 *line = SM.getInstantiationLineNumber(InstLoc);
2786 if (column)
2787 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002788 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002789 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002790}
2791
Douglas Gregora9b06d42010-11-09 06:24:54 +00002792void clang_getSpellingLocation(CXSourceLocation location,
2793 CXFile *file,
2794 unsigned *line,
2795 unsigned *column,
2796 unsigned *offset) {
2797 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2798
2799 if (!location.ptr_data[0] || Loc.isInvalid()) {
2800 if (file)
2801 *file = 0;
2802 if (line)
2803 *line = 0;
2804 if (column)
2805 *column = 0;
2806 if (offset)
2807 *offset = 0;
2808 return;
2809 }
2810
2811 const SourceManager &SM =
2812 *static_cast<const SourceManager*>(location.ptr_data[0]);
2813 SourceLocation SpellLoc = Loc;
2814 if (SpellLoc.isMacroID()) {
2815 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2816 if (SimpleSpellingLoc.isFileID() &&
2817 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2818 SpellLoc = SimpleSpellingLoc;
2819 else
2820 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2821 }
2822
2823 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2824 FileID FID = LocInfo.first;
2825 unsigned FileOffset = LocInfo.second;
2826
2827 if (file)
2828 *file = (void *)SM.getFileEntryForID(FID);
2829 if (line)
2830 *line = SM.getLineNumber(FID, FileOffset);
2831 if (column)
2832 *column = SM.getColumnNumber(FID, FileOffset);
2833 if (offset)
2834 *offset = FileOffset;
2835}
2836
Douglas Gregor1db19de2010-01-19 21:36:55 +00002837CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002838 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002839 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002840 return Result;
2841}
2842
2843CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002844 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002845 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002846 return Result;
2847}
2848
Douglas Gregorb9790342010-01-22 21:44:22 +00002849} // end: extern "C"
2850
Douglas Gregor1db19de2010-01-19 21:36:55 +00002851//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002852// CXFile Operations.
2853//===----------------------------------------------------------------------===//
2854
2855extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002856CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002857 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002858 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002859
Steve Naroff88145032009-10-27 14:35:18 +00002860 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002861 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002862}
2863
2864time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002865 if (!SFile)
2866 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002867
Steve Naroff88145032009-10-27 14:35:18 +00002868 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2869 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002870}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002871
Douglas Gregorb9790342010-01-22 21:44:22 +00002872CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2873 if (!tu)
2874 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002875
Ted Kremeneka60ed472010-11-16 08:15:36 +00002876 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002877
Douglas Gregorb9790342010-01-22 21:44:22 +00002878 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002879 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002880}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002881
Ted Kremenekfb480492010-01-13 21:46:36 +00002882} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002883
Ted Kremenekfb480492010-01-13 21:46:36 +00002884//===----------------------------------------------------------------------===//
2885// CXCursor Operations.
2886//===----------------------------------------------------------------------===//
2887
Ted Kremenekfb480492010-01-13 21:46:36 +00002888static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002889 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2890 return getDeclFromExpr(CE->getSubExpr());
2891
Ted Kremenekfb480492010-01-13 21:46:36 +00002892 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2893 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002894 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2895 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002896 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2897 return ME->getMemberDecl();
2898 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2899 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002900 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002901 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002902
Ted Kremenekfb480492010-01-13 21:46:36 +00002903 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2904 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002905 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2906 if (!CE->isElidable())
2907 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002908 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2909 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002910
Douglas Gregordb1314e2010-10-01 21:11:22 +00002911 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2912 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002913 if (SubstNonTypeTemplateParmPackExpr *NTTP
2914 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2915 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002916 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2917 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2918 isa<ParmVarDecl>(SizeOfPack->getPack()))
2919 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002920
Ted Kremenekfb480492010-01-13 21:46:36 +00002921 return 0;
2922}
2923
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002924static SourceLocation getLocationFromExpr(Expr *E) {
2925 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2926 return /*FIXME:*/Msg->getLeftLoc();
2927 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2928 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002929 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2930 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002931 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2932 return Member->getMemberLoc();
2933 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2934 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002935 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2936 return SizeOfPack->getPackLoc();
2937
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002938 return E->getLocStart();
2939}
2940
Ted Kremenekfb480492010-01-13 21:46:36 +00002941extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002942
2943unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002944 CXCursorVisitor visitor,
2945 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002946 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00002947 getCursorASTUnit(parent)->getMaxPCHLevel(),
2948 false);
Douglas Gregorb1373d02010-01-20 20:59:29 +00002949 return CursorVis.VisitChildren(parent);
2950}
2951
David Chisnall3387c652010-11-03 14:12:26 +00002952#ifndef __has_feature
2953#define __has_feature(x) 0
2954#endif
2955#if __has_feature(blocks)
2956typedef enum CXChildVisitResult
2957 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2958
2959static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2960 CXClientData client_data) {
2961 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2962 return block(cursor, parent);
2963}
2964#else
2965// If we are compiled with a compiler that doesn't have native blocks support,
2966// define and call the block manually, so the
2967typedef struct _CXChildVisitResult
2968{
2969 void *isa;
2970 int flags;
2971 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002972 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2973 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002974} *CXCursorVisitorBlock;
2975
2976static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2977 CXClientData client_data) {
2978 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2979 return block->invoke(block, cursor, parent);
2980}
2981#endif
2982
2983
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002984unsigned clang_visitChildrenWithBlock(CXCursor parent,
2985 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002986 return clang_visitChildren(parent, visitWithBlock, block);
2987}
2988
Douglas Gregor78205d42010-01-20 21:45:58 +00002989static CXString getDeclSpelling(Decl *D) {
2990 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00002991 if (!ND) {
2992 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2993 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2994 return createCXString(Property->getIdentifier()->getName());
2995
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002996 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00002997 }
2998
Douglas Gregor78205d42010-01-20 21:45:58 +00002999 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003000 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003001
Douglas Gregor78205d42010-01-20 21:45:58 +00003002 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
3003 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3004 // and returns different names. NamedDecl returns the class name and
3005 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003006 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003007
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003008 if (isa<UsingDirectiveDecl>(D))
3009 return createCXString("");
3010
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00003011 llvm::SmallString<1024> S;
3012 llvm::raw_svector_ostream os(S);
3013 ND->printName(os);
3014
3015 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00003016}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003017
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003018CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003019 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003020 return clang_getTranslationUnitSpelling(
3021 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003022
Steve Narofff334b4e2009-09-02 18:26:48 +00003023 if (clang_isReference(C.kind)) {
3024 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00003025 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00003026 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003027 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003028 }
3029 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00003030 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003031 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003032 }
3033 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00003034 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00003035 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003036 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003037 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00003038 case CXCursor_CXXBaseSpecifier: {
3039 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3040 return createCXString(B->getType().getAsString());
3041 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003042 case CXCursor_TypeRef: {
3043 TypeDecl *Type = getCursorTypeRef(C).first;
3044 assert(Type && "Missing type decl");
3045
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003046 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3047 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003048 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003049 case CXCursor_TemplateRef: {
3050 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00003051 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003052
3053 return createCXString(Template->getNameAsString());
3054 }
Douglas Gregor69319002010-08-31 23:48:11 +00003055
3056 case CXCursor_NamespaceRef: {
3057 NamedDecl *NS = getCursorNamespaceRef(C).first;
3058 assert(NS && "Missing namespace decl");
3059
3060 return createCXString(NS->getNameAsString());
3061 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003062
Douglas Gregora67e03f2010-09-09 21:42:20 +00003063 case CXCursor_MemberRef: {
3064 FieldDecl *Field = getCursorMemberRef(C).first;
3065 assert(Field && "Missing member decl");
3066
3067 return createCXString(Field->getNameAsString());
3068 }
3069
Douglas Gregor36897b02010-09-10 00:22:18 +00003070 case CXCursor_LabelRef: {
3071 LabelStmt *Label = getCursorLabelRef(C).first;
3072 assert(Label && "Missing label");
3073
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003074 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003075 }
3076
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003077 case CXCursor_OverloadedDeclRef: {
3078 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3079 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3080 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3081 return createCXString(ND->getNameAsString());
3082 return createCXString("");
3083 }
3084 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3085 return createCXString(E->getName().getAsString());
3086 OverloadedTemplateStorage *Ovl
3087 = Storage.get<OverloadedTemplateStorage*>();
3088 if (Ovl->size() == 0)
3089 return createCXString("");
3090 return createCXString((*Ovl->begin())->getNameAsString());
3091 }
3092
Daniel Dunbaracca7252009-11-30 20:42:49 +00003093 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003094 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003095 }
3096 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003097
3098 if (clang_isExpression(C.kind)) {
3099 Decl *D = getDeclFromExpr(getCursorExpr(C));
3100 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003101 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003102 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003103 }
3104
Douglas Gregor36897b02010-09-10 00:22:18 +00003105 if (clang_isStatement(C.kind)) {
3106 Stmt *S = getCursorStmt(C);
3107 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003108 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003109
3110 return createCXString("");
3111 }
3112
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003113 if (C.kind == CXCursor_MacroInstantiation)
3114 return createCXString(getCursorMacroInstantiation(C)->getName()
3115 ->getNameStart());
3116
Douglas Gregor572feb22010-03-18 18:04:21 +00003117 if (C.kind == CXCursor_MacroDefinition)
3118 return createCXString(getCursorMacroDefinition(C)->getName()
3119 ->getNameStart());
3120
Douglas Gregorecdcb882010-10-20 22:00:55 +00003121 if (C.kind == CXCursor_InclusionDirective)
3122 return createCXString(getCursorInclusionDirective(C)->getFileName());
3123
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003124 if (clang_isDeclaration(C.kind))
3125 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003126
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003127 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003128}
3129
Douglas Gregor358559d2010-10-02 22:49:11 +00003130CXString clang_getCursorDisplayName(CXCursor C) {
3131 if (!clang_isDeclaration(C.kind))
3132 return clang_getCursorSpelling(C);
3133
3134 Decl *D = getCursorDecl(C);
3135 if (!D)
3136 return createCXString("");
3137
3138 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3139 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3140 D = FunTmpl->getTemplatedDecl();
3141
3142 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3143 llvm::SmallString<64> Str;
3144 llvm::raw_svector_ostream OS(Str);
3145 OS << Function->getNameAsString();
3146 if (Function->getPrimaryTemplate())
3147 OS << "<>";
3148 OS << "(";
3149 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3150 if (I)
3151 OS << ", ";
3152 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3153 }
3154
3155 if (Function->isVariadic()) {
3156 if (Function->getNumParams())
3157 OS << ", ";
3158 OS << "...";
3159 }
3160 OS << ")";
3161 return createCXString(OS.str());
3162 }
3163
3164 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3165 llvm::SmallString<64> Str;
3166 llvm::raw_svector_ostream OS(Str);
3167 OS << ClassTemplate->getNameAsString();
3168 OS << "<";
3169 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3170 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3171 if (I)
3172 OS << ", ";
3173
3174 NamedDecl *Param = Params->getParam(I);
3175 if (Param->getIdentifier()) {
3176 OS << Param->getIdentifier()->getName();
3177 continue;
3178 }
3179
3180 // There is no parameter name, which makes this tricky. Try to come up
3181 // with something useful that isn't too long.
3182 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3183 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3184 else if (NonTypeTemplateParmDecl *NTTP
3185 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3186 OS << NTTP->getType().getAsString(Policy);
3187 else
3188 OS << "template<...> class";
3189 }
3190
3191 OS << ">";
3192 return createCXString(OS.str());
3193 }
3194
3195 if (ClassTemplateSpecializationDecl *ClassSpec
3196 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3197 // If the type was explicitly written, use that.
3198 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3199 return createCXString(TSInfo->getType().getAsString(Policy));
3200
3201 llvm::SmallString<64> Str;
3202 llvm::raw_svector_ostream OS(Str);
3203 OS << ClassSpec->getNameAsString();
3204 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003205 ClassSpec->getTemplateArgs().data(),
3206 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003207 Policy);
3208 return createCXString(OS.str());
3209 }
3210
3211 return clang_getCursorSpelling(C);
3212}
3213
Ted Kremeneke68fff62010-02-17 00:41:32 +00003214CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003215 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003216 case CXCursor_FunctionDecl:
3217 return createCXString("FunctionDecl");
3218 case CXCursor_TypedefDecl:
3219 return createCXString("TypedefDecl");
3220 case CXCursor_EnumDecl:
3221 return createCXString("EnumDecl");
3222 case CXCursor_EnumConstantDecl:
3223 return createCXString("EnumConstantDecl");
3224 case CXCursor_StructDecl:
3225 return createCXString("StructDecl");
3226 case CXCursor_UnionDecl:
3227 return createCXString("UnionDecl");
3228 case CXCursor_ClassDecl:
3229 return createCXString("ClassDecl");
3230 case CXCursor_FieldDecl:
3231 return createCXString("FieldDecl");
3232 case CXCursor_VarDecl:
3233 return createCXString("VarDecl");
3234 case CXCursor_ParmDecl:
3235 return createCXString("ParmDecl");
3236 case CXCursor_ObjCInterfaceDecl:
3237 return createCXString("ObjCInterfaceDecl");
3238 case CXCursor_ObjCCategoryDecl:
3239 return createCXString("ObjCCategoryDecl");
3240 case CXCursor_ObjCProtocolDecl:
3241 return createCXString("ObjCProtocolDecl");
3242 case CXCursor_ObjCPropertyDecl:
3243 return createCXString("ObjCPropertyDecl");
3244 case CXCursor_ObjCIvarDecl:
3245 return createCXString("ObjCIvarDecl");
3246 case CXCursor_ObjCInstanceMethodDecl:
3247 return createCXString("ObjCInstanceMethodDecl");
3248 case CXCursor_ObjCClassMethodDecl:
3249 return createCXString("ObjCClassMethodDecl");
3250 case CXCursor_ObjCImplementationDecl:
3251 return createCXString("ObjCImplementationDecl");
3252 case CXCursor_ObjCCategoryImplDecl:
3253 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003254 case CXCursor_CXXMethod:
3255 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003256 case CXCursor_UnexposedDecl:
3257 return createCXString("UnexposedDecl");
3258 case CXCursor_ObjCSuperClassRef:
3259 return createCXString("ObjCSuperClassRef");
3260 case CXCursor_ObjCProtocolRef:
3261 return createCXString("ObjCProtocolRef");
3262 case CXCursor_ObjCClassRef:
3263 return createCXString("ObjCClassRef");
3264 case CXCursor_TypeRef:
3265 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003266 case CXCursor_TemplateRef:
3267 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003268 case CXCursor_NamespaceRef:
3269 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003270 case CXCursor_MemberRef:
3271 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003272 case CXCursor_LabelRef:
3273 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003274 case CXCursor_OverloadedDeclRef:
3275 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003276 case CXCursor_UnexposedExpr:
3277 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003278 case CXCursor_BlockExpr:
3279 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003280 case CXCursor_DeclRefExpr:
3281 return createCXString("DeclRefExpr");
3282 case CXCursor_MemberRefExpr:
3283 return createCXString("MemberRefExpr");
3284 case CXCursor_CallExpr:
3285 return createCXString("CallExpr");
3286 case CXCursor_ObjCMessageExpr:
3287 return createCXString("ObjCMessageExpr");
3288 case CXCursor_UnexposedStmt:
3289 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003290 case CXCursor_LabelStmt:
3291 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003292 case CXCursor_InvalidFile:
3293 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003294 case CXCursor_InvalidCode:
3295 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003296 case CXCursor_NoDeclFound:
3297 return createCXString("NoDeclFound");
3298 case CXCursor_NotImplemented:
3299 return createCXString("NotImplemented");
3300 case CXCursor_TranslationUnit:
3301 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003302 case CXCursor_UnexposedAttr:
3303 return createCXString("UnexposedAttr");
3304 case CXCursor_IBActionAttr:
3305 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003306 case CXCursor_IBOutletAttr:
3307 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003308 case CXCursor_IBOutletCollectionAttr:
3309 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003310 case CXCursor_PreprocessingDirective:
3311 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003312 case CXCursor_MacroDefinition:
3313 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003314 case CXCursor_MacroInstantiation:
3315 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003316 case CXCursor_InclusionDirective:
3317 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003318 case CXCursor_Namespace:
3319 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003320 case CXCursor_LinkageSpec:
3321 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003322 case CXCursor_CXXBaseSpecifier:
3323 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003324 case CXCursor_Constructor:
3325 return createCXString("CXXConstructor");
3326 case CXCursor_Destructor:
3327 return createCXString("CXXDestructor");
3328 case CXCursor_ConversionFunction:
3329 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003330 case CXCursor_TemplateTypeParameter:
3331 return createCXString("TemplateTypeParameter");
3332 case CXCursor_NonTypeTemplateParameter:
3333 return createCXString("NonTypeTemplateParameter");
3334 case CXCursor_TemplateTemplateParameter:
3335 return createCXString("TemplateTemplateParameter");
3336 case CXCursor_FunctionTemplate:
3337 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003338 case CXCursor_ClassTemplate:
3339 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003340 case CXCursor_ClassTemplatePartialSpecialization:
3341 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003342 case CXCursor_NamespaceAlias:
3343 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003344 case CXCursor_UsingDirective:
3345 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003346 case CXCursor_UsingDeclaration:
3347 return createCXString("UsingDeclaration");
Richard Smith162e1c12011-04-15 14:24:37 +00003348 case CXCursor_TypeAliasDecl:
3349 return createCXString("TypeAliasDecl");
Steve Naroff89922f82009-08-31 00:59:03 +00003350 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003351
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003352 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003353 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003354}
Steve Naroff89922f82009-08-31 00:59:03 +00003355
Ted Kremeneke68fff62010-02-17 00:41:32 +00003356enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3357 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003358 CXClientData client_data) {
3359 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003360
3361 // If our current best cursor is the construction of a temporary object,
3362 // don't replace that cursor with a type reference, because we want
3363 // clang_getCursor() to point at the constructor.
3364 if (clang_isExpression(BestCursor->kind) &&
3365 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3366 cursor.kind == CXCursor_TypeRef)
3367 return CXChildVisit_Recurse;
3368
Douglas Gregor85fe1562010-12-10 07:23:11 +00003369 // Don't override a preprocessing cursor with another preprocessing
3370 // cursor; we want the outermost preprocessing cursor.
3371 if (clang_isPreprocessing(cursor.kind) &&
3372 clang_isPreprocessing(BestCursor->kind))
3373 return CXChildVisit_Recurse;
3374
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003375 *BestCursor = cursor;
3376 return CXChildVisit_Recurse;
3377}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003378
Douglas Gregorb9790342010-01-22 21:44:22 +00003379CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3380 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003381 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003382
Ted Kremeneka60ed472010-11-16 08:15:36 +00003383 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003384 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3385
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003386 // Translate the given source location to make it point at the beginning of
3387 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003388 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003389
3390 // Guard against an invalid SourceLocation, or we may assert in one
3391 // of the following calls.
3392 if (SLoc.isInvalid())
3393 return clang_getNullCursor();
3394
Douglas Gregor40749ee2010-11-03 00:35:38 +00003395 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003396 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3397 CXXUnit->getASTContext().getLangOptions());
3398
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003399 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3400 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003401 // FIXME: Would be great to have a "hint" cursor, then walk from that
3402 // hint cursor upward until we find a cursor whose source range encloses
3403 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003404 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3405 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00003406 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003407 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003408 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003409
3410 if (Logging) {
3411 CXFile SearchFile;
3412 unsigned SearchLine, SearchColumn;
3413 CXFile ResultFile;
3414 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003415 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3416 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003417 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3418
3419 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3420 0);
3421 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3422 &ResultColumn, 0);
3423 SearchFileName = clang_getFileName(SearchFile);
3424 ResultFileName = clang_getFileName(ResultFile);
3425 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003426 USR = clang_getCursorUSR(Result);
3427 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003428 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3429 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003430 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3431 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003432 clang_disposeString(SearchFileName);
3433 clang_disposeString(ResultFileName);
3434 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003435 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003436
3437 CXCursor Definition = clang_getCursorDefinition(Result);
3438 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3439 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3440 CXString DefinitionKindSpelling
3441 = clang_getCursorKindSpelling(Definition.kind);
3442 CXFile DefinitionFile;
3443 unsigned DefinitionLine, DefinitionColumn;
3444 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3445 &DefinitionLine, &DefinitionColumn, 0);
3446 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3447 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3448 clang_getCString(DefinitionKindSpelling),
3449 clang_getCString(DefinitionFileName),
3450 DefinitionLine, DefinitionColumn);
3451 clang_disposeString(DefinitionFileName);
3452 clang_disposeString(DefinitionKindSpelling);
3453 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003454 }
3455
Ted Kremeneke68fff62010-02-17 00:41:32 +00003456 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003457}
3458
Ted Kremenek73885552009-11-17 19:28:59 +00003459CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003460 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003461}
3462
3463unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003464 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003465}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003466
Douglas Gregor9ce55842010-11-20 00:09:34 +00003467unsigned clang_hashCursor(CXCursor C) {
3468 unsigned Index = 0;
3469 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3470 Index = 1;
3471
3472 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3473 std::make_pair(C.kind, C.data[Index]));
3474}
3475
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003476unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003477 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3478}
3479
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003480unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003481 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3482}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003483
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003484unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003485 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3486}
3487
Douglas Gregor97b98722010-01-19 23:20:36 +00003488unsigned clang_isExpression(enum CXCursorKind K) {
3489 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3490}
3491
3492unsigned clang_isStatement(enum CXCursorKind K) {
3493 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3494}
3495
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003496unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3497 return K == CXCursor_TranslationUnit;
3498}
3499
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003500unsigned clang_isPreprocessing(enum CXCursorKind K) {
3501 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3502}
3503
Ted Kremenekad6eff62010-03-08 21:17:29 +00003504unsigned clang_isUnexposed(enum CXCursorKind K) {
3505 switch (K) {
3506 case CXCursor_UnexposedDecl:
3507 case CXCursor_UnexposedExpr:
3508 case CXCursor_UnexposedStmt:
3509 case CXCursor_UnexposedAttr:
3510 return true;
3511 default:
3512 return false;
3513 }
3514}
3515
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003516CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003517 return C.kind;
3518}
3519
Douglas Gregor98258af2010-01-18 22:46:11 +00003520CXSourceLocation clang_getCursorLocation(CXCursor C) {
3521 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003522 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003523 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003524 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3525 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003526 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003527 }
3528
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003529 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003530 std::pair<ObjCProtocolDecl *, SourceLocation> P
3531 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003532 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003533 }
3534
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003535 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003536 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3537 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003538 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003539 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003540
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003541 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003542 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003543 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003544 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003545
3546 case CXCursor_TemplateRef: {
3547 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3548 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3549 }
3550
Douglas Gregor69319002010-08-31 23:48:11 +00003551 case CXCursor_NamespaceRef: {
3552 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3553 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3554 }
3555
Douglas Gregora67e03f2010-09-09 21:42:20 +00003556 case CXCursor_MemberRef: {
3557 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3558 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3559 }
3560
Ted Kremenek3064ef92010-08-27 21:34:58 +00003561 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003562 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3563 if (!BaseSpec)
3564 return clang_getNullLocation();
3565
3566 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3567 return cxloc::translateSourceLocation(getCursorContext(C),
3568 TSInfo->getTypeLoc().getBeginLoc());
3569
3570 return cxloc::translateSourceLocation(getCursorContext(C),
3571 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003572 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003573
Douglas Gregor36897b02010-09-10 00:22:18 +00003574 case CXCursor_LabelRef: {
3575 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3576 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3577 }
3578
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003579 case CXCursor_OverloadedDeclRef:
3580 return cxloc::translateSourceLocation(getCursorContext(C),
3581 getCursorOverloadedDeclRef(C).second);
3582
Douglas Gregorf46034a2010-01-18 23:41:10 +00003583 default:
3584 // FIXME: Need a way to enumerate all non-reference cases.
3585 llvm_unreachable("Missed a reference kind");
3586 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003587 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003588
3589 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003590 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003591 getLocationFromExpr(getCursorExpr(C)));
3592
Douglas Gregor36897b02010-09-10 00:22:18 +00003593 if (clang_isStatement(C.kind))
3594 return cxloc::translateSourceLocation(getCursorContext(C),
3595 getCursorStmt(C)->getLocStart());
3596
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003597 if (C.kind == CXCursor_PreprocessingDirective) {
3598 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3599 return cxloc::translateSourceLocation(getCursorContext(C), L);
3600 }
Douglas Gregor48072312010-03-18 15:23:44 +00003601
3602 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003603 SourceLocation L
3604 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003605 return cxloc::translateSourceLocation(getCursorContext(C), L);
3606 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003607
3608 if (C.kind == CXCursor_MacroDefinition) {
3609 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3610 return cxloc::translateSourceLocation(getCursorContext(C), L);
3611 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003612
3613 if (C.kind == CXCursor_InclusionDirective) {
3614 SourceLocation L
3615 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3616 return cxloc::translateSourceLocation(getCursorContext(C), L);
3617 }
3618
Ted Kremenek9a700d22010-05-12 06:16:13 +00003619 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003620 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003621
Douglas Gregorf46034a2010-01-18 23:41:10 +00003622 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003623 SourceLocation Loc = D->getLocation();
3624 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3625 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003626 // FIXME: Multiple variables declared in a single declaration
3627 // currently lack the information needed to correctly determine their
3628 // ranges when accounting for the type-specifier. We use context
3629 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3630 // and if so, whether it is the first decl.
3631 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3632 if (!cxcursor::isFirstInDeclGroup(C))
3633 Loc = VD->getLocation();
3634 }
3635
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003636 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003637}
Douglas Gregora7bde202010-01-19 00:34:46 +00003638
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003639} // end extern "C"
3640
3641static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003642 if (clang_isReference(C.kind)) {
3643 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003644 case CXCursor_ObjCSuperClassRef:
3645 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003646
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003647 case CXCursor_ObjCProtocolRef:
3648 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003649
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003650 case CXCursor_ObjCClassRef:
3651 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003652
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003653 case CXCursor_TypeRef:
3654 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003655
3656 case CXCursor_TemplateRef:
3657 return getCursorTemplateRef(C).second;
3658
Douglas Gregor69319002010-08-31 23:48:11 +00003659 case CXCursor_NamespaceRef:
3660 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003661
3662 case CXCursor_MemberRef:
3663 return getCursorMemberRef(C).second;
3664
Ted Kremenek3064ef92010-08-27 21:34:58 +00003665 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003666 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003667
Douglas Gregor36897b02010-09-10 00:22:18 +00003668 case CXCursor_LabelRef:
3669 return getCursorLabelRef(C).second;
3670
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003671 case CXCursor_OverloadedDeclRef:
3672 return getCursorOverloadedDeclRef(C).second;
3673
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003674 default:
3675 // FIXME: Need a way to enumerate all non-reference cases.
3676 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003677 }
3678 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003679
3680 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003681 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003682
3683 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003684 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003685
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003686 if (C.kind == CXCursor_PreprocessingDirective)
3687 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003688
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003689 if (C.kind == CXCursor_MacroInstantiation)
3690 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003691
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003692 if (C.kind == CXCursor_MacroDefinition)
3693 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003694
3695 if (C.kind == CXCursor_InclusionDirective)
3696 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3697
Ted Kremenek007a7c92010-11-01 23:26:51 +00003698 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3699 Decl *D = cxcursor::getCursorDecl(C);
3700 SourceRange R = D->getSourceRange();
3701 // FIXME: Multiple variables declared in a single declaration
3702 // currently lack the information needed to correctly determine their
3703 // ranges when accounting for the type-specifier. We use context
3704 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3705 // and if so, whether it is the first decl.
3706 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3707 if (!cxcursor::isFirstInDeclGroup(C))
3708 R.setBegin(VD->getLocation());
3709 }
3710 return R;
3711 }
Douglas Gregor66537982010-11-17 17:14:07 +00003712 return SourceRange();
3713}
3714
3715/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3716/// the decl-specifier-seq for declarations.
3717static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3718 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3719 Decl *D = cxcursor::getCursorDecl(C);
3720 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003721
Douglas Gregor2494dd02011-03-01 01:34:45 +00003722 // Adjust the start of the location for declarations preceded by
3723 // declaration specifiers.
3724 SourceLocation StartLoc;
3725 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3726 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3727 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3728 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3729 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3730 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3731 }
3732
3733 if (StartLoc.isValid() && R.getBegin().isValid() &&
3734 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3735 R.setBegin(StartLoc);
3736
3737 // FIXME: Multiple variables declared in a single declaration
3738 // currently lack the information needed to correctly determine their
3739 // ranges when accounting for the type-specifier. We use context
3740 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3741 // and if so, whether it is the first decl.
3742 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3743 if (!cxcursor::isFirstInDeclGroup(C))
3744 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003745 }
3746
3747 return R;
3748 }
3749
3750 return getRawCursorExtent(C);
3751}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003752
3753extern "C" {
3754
3755CXSourceRange clang_getCursorExtent(CXCursor C) {
3756 SourceRange R = getRawCursorExtent(C);
3757 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003758 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003759
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003760 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003761}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003762
3763CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003764 if (clang_isInvalid(C.kind))
3765 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003766
Ted Kremeneka60ed472010-11-16 08:15:36 +00003767 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003768 if (clang_isDeclaration(C.kind)) {
3769 Decl *D = getCursorDecl(C);
3770 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003771 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003772 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003773 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003774 if (ObjCForwardProtocolDecl *Protocols
3775 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003776 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003777 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3778 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3779 return MakeCXCursor(Property, tu);
3780
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003781 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003782 }
3783
Douglas Gregor97b98722010-01-19 23:20:36 +00003784 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003785 Expr *E = getCursorExpr(C);
3786 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003787 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003788 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003789
3790 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003791 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003792
Douglas Gregor97b98722010-01-19 23:20:36 +00003793 return clang_getNullCursor();
3794 }
3795
Douglas Gregor36897b02010-09-10 00:22:18 +00003796 if (clang_isStatement(C.kind)) {
3797 Stmt *S = getCursorStmt(C);
3798 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek37c2e962011-03-15 23:47:49 +00003799 if (LabelDecl *label = Goto->getLabel())
3800 if (LabelStmt *labelS = label->getStmt())
3801 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003802
3803 return clang_getNullCursor();
3804 }
3805
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003806 if (C.kind == CXCursor_MacroInstantiation) {
3807 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003808 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003809 }
3810
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003811 if (!clang_isReference(C.kind))
3812 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003813
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003814 switch (C.kind) {
3815 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003816 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003817
3818 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003819 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003820
3821 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003822 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003823
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003824 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003825 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003826
3827 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003828 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003829
Douglas Gregor69319002010-08-31 23:48:11 +00003830 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003831 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003832
Douglas Gregora67e03f2010-09-09 21:42:20 +00003833 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003834 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003835
Ted Kremenek3064ef92010-08-27 21:34:58 +00003836 case CXCursor_CXXBaseSpecifier: {
3837 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3838 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003839 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003840 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003841
Douglas Gregor36897b02010-09-10 00:22:18 +00003842 case CXCursor_LabelRef:
3843 // FIXME: We end up faking the "parent" declaration here because we
3844 // don't want to make CXCursor larger.
3845 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003846 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3847 .getTranslationUnitDecl(),
3848 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003849
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003850 case CXCursor_OverloadedDeclRef:
3851 return C;
3852
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003853 default:
3854 // We would prefer to enumerate all non-reference cursor kinds here.
3855 llvm_unreachable("Unhandled reference cursor kind");
3856 break;
3857 }
3858 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003859
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003860 return clang_getNullCursor();
3861}
3862
Douglas Gregorb6998662010-01-19 19:34:47 +00003863CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003864 if (clang_isInvalid(C.kind))
3865 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003866
Ted Kremeneka60ed472010-11-16 08:15:36 +00003867 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003868
Douglas Gregorb6998662010-01-19 19:34:47 +00003869 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003870 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003871 C = clang_getCursorReferenced(C);
3872 WasReference = true;
3873 }
3874
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003875 if (C.kind == CXCursor_MacroInstantiation)
3876 return clang_getCursorReferenced(C);
3877
Douglas Gregorb6998662010-01-19 19:34:47 +00003878 if (!clang_isDeclaration(C.kind))
3879 return clang_getNullCursor();
3880
3881 Decl *D = getCursorDecl(C);
3882 if (!D)
3883 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003884
Douglas Gregorb6998662010-01-19 19:34:47 +00003885 switch (D->getKind()) {
3886 // Declaration kinds that don't really separate the notions of
3887 // declaration and definition.
3888 case Decl::Namespace:
3889 case Decl::Typedef:
Richard Smith162e1c12011-04-15 14:24:37 +00003890 case Decl::TypeAlias:
Douglas Gregorb6998662010-01-19 19:34:47 +00003891 case Decl::TemplateTypeParm:
3892 case Decl::EnumConstant:
3893 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003894 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003895 case Decl::ObjCIvar:
3896 case Decl::ObjCAtDefsField:
3897 case Decl::ImplicitParam:
3898 case Decl::ParmVar:
3899 case Decl::NonTypeTemplateParm:
3900 case Decl::TemplateTemplateParm:
3901 case Decl::ObjCCategoryImpl:
3902 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003903 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003904 case Decl::LinkageSpec:
3905 case Decl::ObjCPropertyImpl:
3906 case Decl::FileScopeAsm:
3907 case Decl::StaticAssert:
3908 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003909 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003910 return C;
3911
3912 // Declaration kinds that don't make any sense here, but are
3913 // nonetheless harmless.
3914 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003915 break;
3916
3917 // Declaration kinds for which the definition is not resolvable.
3918 case Decl::UnresolvedUsingTypename:
3919 case Decl::UnresolvedUsingValue:
3920 break;
3921
3922 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003923 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003924 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003925
3926 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003927 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003928
3929 case Decl::Enum:
3930 case Decl::Record:
3931 case Decl::CXXRecord:
3932 case Decl::ClassTemplateSpecialization:
3933 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003934 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003935 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003936 return clang_getNullCursor();
3937
3938 case Decl::Function:
3939 case Decl::CXXMethod:
3940 case Decl::CXXConstructor:
3941 case Decl::CXXDestructor:
3942 case Decl::CXXConversion: {
3943 const FunctionDecl *Def = 0;
3944 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003945 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003946 return clang_getNullCursor();
3947 }
3948
3949 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003950 // Ask the variable if it has a definition.
3951 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003952 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003953 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003954 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003955
Douglas Gregorb6998662010-01-19 19:34:47 +00003956 case Decl::FunctionTemplate: {
3957 const FunctionDecl *Def = 0;
3958 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003959 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003960 return clang_getNullCursor();
3961 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003962
Douglas Gregorb6998662010-01-19 19:34:47 +00003963 case Decl::ClassTemplate: {
3964 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003965 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003966 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003967 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003968 return clang_getNullCursor();
3969 }
3970
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003971 case Decl::Using:
3972 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003973 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003974
3975 case Decl::UsingShadow:
3976 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003977 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003978 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003979
3980 case Decl::ObjCMethod: {
3981 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3982 if (Method->isThisDeclarationADefinition())
3983 return C;
3984
3985 // Dig out the method definition in the associated
3986 // @implementation, if we have it.
3987 // FIXME: The ASTs should make finding the definition easier.
3988 if (ObjCInterfaceDecl *Class
3989 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3990 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3991 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3992 Method->isInstanceMethod()))
3993 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003994 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003995
3996 return clang_getNullCursor();
3997 }
3998
3999 case Decl::ObjCCategory:
4000 if (ObjCCategoryImplDecl *Impl
4001 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004002 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004003 return clang_getNullCursor();
4004
4005 case Decl::ObjCProtocol:
4006 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
4007 return C;
4008 return clang_getNullCursor();
4009
4010 case Decl::ObjCInterface:
4011 // There are two notions of a "definition" for an Objective-C
4012 // class: the interface and its implementation. When we resolved a
4013 // reference to an Objective-C class, produce the @interface as
4014 // the definition; when we were provided with the interface,
4015 // produce the @implementation as the definition.
4016 if (WasReference) {
4017 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4018 return C;
4019 } else if (ObjCImplementationDecl *Impl
4020 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004021 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004022 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004023
Douglas Gregorb6998662010-01-19 19:34:47 +00004024 case Decl::ObjCProperty:
4025 // FIXME: We don't really know where to find the
4026 // ObjCPropertyImplDecls that implement this property.
4027 return clang_getNullCursor();
4028
4029 case Decl::ObjCCompatibleAlias:
4030 if (ObjCInterfaceDecl *Class
4031 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4032 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004033 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004034
Douglas Gregorb6998662010-01-19 19:34:47 +00004035 return clang_getNullCursor();
4036
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004037 case Decl::ObjCForwardProtocol:
4038 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004039 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004040
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004041 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004042 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004043 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004044
4045 case Decl::Friend:
4046 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004047 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004048 return clang_getNullCursor();
4049
4050 case Decl::FriendTemplate:
4051 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004052 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004053 return clang_getNullCursor();
4054 }
4055
4056 return clang_getNullCursor();
4057}
4058
4059unsigned clang_isCursorDefinition(CXCursor C) {
4060 if (!clang_isDeclaration(C.kind))
4061 return 0;
4062
4063 return clang_getCursorDefinition(C) == C;
4064}
4065
Douglas Gregor1a9d0502010-11-19 23:44:15 +00004066CXCursor clang_getCanonicalCursor(CXCursor C) {
4067 if (!clang_isDeclaration(C.kind))
4068 return C;
4069
4070 if (Decl *D = getCursorDecl(C))
4071 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4072
4073 return C;
4074}
4075
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004076unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004077 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004078 return 0;
4079
4080 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4081 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4082 return E->getNumDecls();
4083
4084 if (OverloadedTemplateStorage *S
4085 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4086 return S->size();
4087
4088 Decl *D = Storage.get<Decl*>();
4089 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00004090 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004091 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4092 return Classes->size();
4093 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4094 return Protocols->protocol_size();
4095
4096 return 0;
4097}
4098
4099CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004100 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004101 return clang_getNullCursor();
4102
4103 if (index >= clang_getNumOverloadedDecls(cursor))
4104 return clang_getNullCursor();
4105
Ted Kremeneka60ed472010-11-16 08:15:36 +00004106 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004107 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4108 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004109 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004110
4111 if (OverloadedTemplateStorage *S
4112 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004113 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004114
4115 Decl *D = Storage.get<Decl*>();
4116 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4117 // FIXME: This is, unfortunately, linear time.
4118 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4119 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004120 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004121 }
4122
4123 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004124 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004125
4126 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004127 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004128
4129 return clang_getNullCursor();
4130}
4131
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004132void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004133 const char **startBuf,
4134 const char **endBuf,
4135 unsigned *startLine,
4136 unsigned *startColumn,
4137 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004138 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004139 assert(getCursorDecl(C) && "CXCursor has null decl");
4140 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004141 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4142 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004143
Steve Naroff4ade6d62009-09-23 17:52:52 +00004144 SourceManager &SM = FD->getASTContext().getSourceManager();
4145 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4146 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4147 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4148 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4149 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4150 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4151}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004152
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004153void clang_enableStackTraces(void) {
4154 llvm::sys::PrintStackTraceOnErrorSignal();
4155}
4156
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004157void clang_executeOnThread(void (*fn)(void*), void *user_data,
4158 unsigned stack_size) {
4159 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4160}
4161
Ted Kremenekfb480492010-01-13 21:46:36 +00004162} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004163
Ted Kremenekfb480492010-01-13 21:46:36 +00004164//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004165// Token-based Operations.
4166//===----------------------------------------------------------------------===//
4167
4168/* CXToken layout:
4169 * int_data[0]: a CXTokenKind
4170 * int_data[1]: starting token location
4171 * int_data[2]: token length
4172 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004173 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004174 * otherwise unused.
4175 */
4176extern "C" {
4177
4178CXTokenKind clang_getTokenKind(CXToken CXTok) {
4179 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4180}
4181
4182CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4183 switch (clang_getTokenKind(CXTok)) {
4184 case CXToken_Identifier:
4185 case CXToken_Keyword:
4186 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004187 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4188 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004189
4190 case CXToken_Literal: {
4191 // We have stashed the starting pointer in the ptr_data field. Use it.
4192 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004193 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004194 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004195
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004196 case CXToken_Punctuation:
4197 case CXToken_Comment:
4198 break;
4199 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004200
4201 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004202 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004203 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004204 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004205 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004206
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004207 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4208 std::pair<FileID, unsigned> LocInfo
4209 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004210 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004211 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004212 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4213 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004214 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004215
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004216 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004217}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004218
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004219CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004220 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004221 if (!CXXUnit)
4222 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004223
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004224 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4225 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4226}
4227
4228CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004229 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004230 if (!CXXUnit)
4231 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004232
4233 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004234 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4235}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004236
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004237void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4238 CXToken **Tokens, unsigned *NumTokens) {
4239 if (Tokens)
4240 *Tokens = 0;
4241 if (NumTokens)
4242 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004243
Ted Kremeneka60ed472010-11-16 08:15:36 +00004244 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004245 if (!CXXUnit || !Tokens || !NumTokens)
4246 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004247
Douglas Gregorbdf60622010-03-05 21:16:25 +00004248 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4249
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004250 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004251 if (R.isInvalid())
4252 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004253
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004254 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4255 std::pair<FileID, unsigned> BeginLocInfo
4256 = SourceMgr.getDecomposedLoc(R.getBegin());
4257 std::pair<FileID, unsigned> EndLocInfo
4258 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004259
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004260 // Cannot tokenize across files.
4261 if (BeginLocInfo.first != EndLocInfo.first)
4262 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004263
4264 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004265 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004266 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004267 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004268 if (Invalid)
4269 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004270
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004271 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4272 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004273 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004274 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004275
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004276 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004277 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004278 llvm::SmallVector<CXToken, 32> CXTokens;
4279 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004280 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004281 do {
4282 // Lex the next token
4283 Lex.LexFromRawLexer(Tok);
4284 if (Tok.is(tok::eof))
4285 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004286
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004287 // Initialize the CXToken.
4288 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004289
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004290 // - Common fields
4291 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4292 CXTok.int_data[2] = Tok.getLength();
4293 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004294
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004295 // - Kind-specific fields
4296 if (Tok.isLiteral()) {
4297 CXTok.int_data[0] = CXToken_Literal;
4298 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004299 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004300 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004301 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004302 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004303
David Chisnall096428b2010-10-13 21:44:48 +00004304 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004305 CXTok.int_data[0] = CXToken_Keyword;
4306 }
4307 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004308 CXTok.int_data[0] = Tok.is(tok::identifier)
4309 ? CXToken_Identifier
4310 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004311 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004312 CXTok.ptr_data = II;
4313 } else if (Tok.is(tok::comment)) {
4314 CXTok.int_data[0] = CXToken_Comment;
4315 CXTok.ptr_data = 0;
4316 } else {
4317 CXTok.int_data[0] = CXToken_Punctuation;
4318 CXTok.ptr_data = 0;
4319 }
4320 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004321 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004322 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004323
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004324 if (CXTokens.empty())
4325 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004326
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004327 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4328 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4329 *NumTokens = CXTokens.size();
4330}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004331
Ted Kremenek6db61092010-05-05 00:55:15 +00004332void clang_disposeTokens(CXTranslationUnit TU,
4333 CXToken *Tokens, unsigned NumTokens) {
4334 free(Tokens);
4335}
4336
4337} // end: extern "C"
4338
4339//===----------------------------------------------------------------------===//
4340// Token annotation APIs.
4341//===----------------------------------------------------------------------===//
4342
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004343typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004344static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4345 CXCursor parent,
4346 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004347namespace {
4348class AnnotateTokensWorker {
4349 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004350 CXToken *Tokens;
4351 CXCursor *Cursors;
4352 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004353 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004354 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004355 CursorVisitor AnnotateVis;
4356 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004357 bool HasContextSensitiveKeywords;
4358
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004359 bool MoreTokens() const { return TokIdx < NumTokens; }
4360 unsigned NextToken() const { return TokIdx; }
4361 void AdvanceToken() { ++TokIdx; }
4362 SourceLocation GetTokenLoc(unsigned tokI) {
4363 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4364 }
4365
Ted Kremenek6db61092010-05-05 00:55:15 +00004366public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004367 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004368 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004369 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004370 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004371 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004372 AnnotateVis(tu,
4373 AnnotateTokensVisitor, this,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00004374 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004375 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4376 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004377
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004378 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004379 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004380 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004381 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004382 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004383 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004384
4385 /// \brief Determine whether the annotator saw any cursors that have
4386 /// context-sensitive keywords.
4387 bool hasContextSensitiveKeywords() const {
4388 return HasContextSensitiveKeywords;
4389 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004390};
4391}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004392
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004393void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4394 // Walk the AST within the region of interest, annotating tokens
4395 // along the way.
4396 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004397
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004398 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4399 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004400 if (Pos != Annotated.end() &&
4401 (clang_isInvalid(Cursors[I].kind) ||
4402 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004403 Cursors[I] = Pos->second;
4404 }
4405
4406 // Finish up annotating any tokens left.
4407 if (!MoreTokens())
4408 return;
4409
4410 const CXCursor &C = clang_getNullCursor();
4411 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4412 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4413 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004414 }
4415}
4416
Ted Kremenek6db61092010-05-05 00:55:15 +00004417enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004418AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004419 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004420 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004421 if (cursorRange.isInvalid())
4422 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004423
4424 if (!HasContextSensitiveKeywords) {
4425 // Objective-C properties can have context-sensitive keywords.
4426 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4427 if (ObjCPropertyDecl *Property
4428 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4429 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4430 }
4431 // Objective-C methods can have context-sensitive keywords.
4432 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4433 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4434 if (ObjCMethodDecl *Method
4435 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4436 if (Method->getObjCDeclQualifier())
4437 HasContextSensitiveKeywords = true;
4438 else {
4439 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4440 PEnd = Method->param_end();
4441 P != PEnd; ++P) {
4442 if ((*P)->getObjCDeclQualifier()) {
4443 HasContextSensitiveKeywords = true;
4444 break;
4445 }
4446 }
4447 }
4448 }
4449 }
4450 // C++ methods can have context-sensitive keywords.
4451 else if (cursor.kind == CXCursor_CXXMethod) {
4452 if (CXXMethodDecl *Method
4453 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4454 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4455 HasContextSensitiveKeywords = true;
4456 }
4457 }
4458 // C++ classes can have context-sensitive keywords.
4459 else if (cursor.kind == CXCursor_StructDecl ||
4460 cursor.kind == CXCursor_ClassDecl ||
4461 cursor.kind == CXCursor_ClassTemplate ||
4462 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4463 if (Decl *D = getCursorDecl(cursor))
4464 if (D->hasAttr<FinalAttr>())
4465 HasContextSensitiveKeywords = true;
4466 }
4467 }
4468
Douglas Gregor4419b672010-10-21 06:10:04 +00004469 if (clang_isPreprocessing(cursor.kind)) {
4470 // For macro instantiations, just note where the beginning of the macro
4471 // instantiation occurs.
4472 if (cursor.kind == CXCursor_MacroInstantiation) {
4473 Annotated[Loc.int_data] = cursor;
4474 return CXChildVisit_Recurse;
4475 }
4476
Douglas Gregor4419b672010-10-21 06:10:04 +00004477 // Items in the preprocessing record are kept separate from items in
4478 // declarations, so we keep a separate token index.
4479 unsigned SavedTokIdx = TokIdx;
4480 TokIdx = PreprocessingTokIdx;
4481
4482 // Skip tokens up until we catch up to the beginning of the preprocessing
4483 // entry.
4484 while (MoreTokens()) {
4485 const unsigned I = NextToken();
4486 SourceLocation TokLoc = GetTokenLoc(I);
4487 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4488 case RangeBefore:
4489 AdvanceToken();
4490 continue;
4491 case RangeAfter:
4492 case RangeOverlap:
4493 break;
4494 }
4495 break;
4496 }
4497
4498 // Look at all of the tokens within this range.
4499 while (MoreTokens()) {
4500 const unsigned I = NextToken();
4501 SourceLocation TokLoc = GetTokenLoc(I);
4502 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4503 case RangeBefore:
4504 assert(0 && "Infeasible");
4505 case RangeAfter:
4506 break;
4507 case RangeOverlap:
4508 Cursors[I] = cursor;
4509 AdvanceToken();
4510 continue;
4511 }
4512 break;
4513 }
4514
4515 // Save the preprocessing token index; restore the non-preprocessing
4516 // token index.
4517 PreprocessingTokIdx = TokIdx;
4518 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004519 return CXChildVisit_Recurse;
4520 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004521
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004522 if (cursorRange.isInvalid())
4523 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004524
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004525 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4526
Ted Kremeneka333c662010-05-12 05:29:33 +00004527 // Adjust the annotated range based specific declarations.
4528 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4529 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004530 Decl *D = cxcursor::getCursorDecl(cursor);
4531 // Don't visit synthesized ObjC methods, since they have no syntatic
4532 // representation in the source.
4533 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4534 if (MD->isSynthesized())
4535 return CXChildVisit_Continue;
4536 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004537
4538 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004539 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004540 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4541 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4542 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4543 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4544 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004545 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004546
4547 if (StartLoc.isValid() && L.isValid() &&
4548 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4549 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004550 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004551
Ted Kremenek3f404602010-08-14 01:14:06 +00004552 // If the location of the cursor occurs within a macro instantiation, record
4553 // the spelling location of the cursor in our annotation map. We can then
4554 // paper over the token labelings during a post-processing step to try and
4555 // get cursor mappings for tokens that are the *arguments* of a macro
4556 // instantiation.
4557 if (L.isMacroID()) {
4558 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4559 // Only invalidate the old annotation if it isn't part of a preprocessing
4560 // directive. Here we assume that the default construction of CXCursor
4561 // results in CXCursor.kind being an initialized value (i.e., 0). If
4562 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004563
Ted Kremenek3f404602010-08-14 01:14:06 +00004564 CXCursor &oldC = Annotated[rawEncoding];
4565 if (!clang_isPreprocessing(oldC.kind))
4566 oldC = cursor;
4567 }
4568
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004569 const enum CXCursorKind K = clang_getCursorKind(parent);
4570 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004571 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4572 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004573
4574 while (MoreTokens()) {
4575 const unsigned I = NextToken();
4576 SourceLocation TokLoc = GetTokenLoc(I);
4577 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4578 case RangeBefore:
4579 Cursors[I] = updateC;
4580 AdvanceToken();
4581 continue;
4582 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004583 case RangeOverlap:
4584 break;
4585 }
4586 break;
4587 }
4588
4589 // Visit children to get their cursor information.
4590 const unsigned BeforeChildren = NextToken();
4591 VisitChildren(cursor);
4592 const unsigned AfterChildren = NextToken();
4593
4594 // Adjust 'Last' to the last token within the extent of the cursor.
4595 while (MoreTokens()) {
4596 const unsigned I = NextToken();
4597 SourceLocation TokLoc = GetTokenLoc(I);
4598 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4599 case RangeBefore:
4600 assert(0 && "Infeasible");
4601 case RangeAfter:
4602 break;
4603 case RangeOverlap:
4604 Cursors[I] = updateC;
4605 AdvanceToken();
4606 continue;
4607 }
4608 break;
4609 }
4610 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004611
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004612 // Scan the tokens that are at the beginning of the cursor, but are not
4613 // capture by the child cursors.
4614
4615 // For AST elements within macros, rely on a post-annotate pass to
4616 // to correctly annotate the tokens with cursors. Otherwise we can
4617 // get confusing results of having tokens that map to cursors that really
4618 // are expanded by an instantiation.
4619 if (L.isMacroID())
4620 cursor = clang_getNullCursor();
4621
4622 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4623 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4624 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004625
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004626 Cursors[I] = cursor;
4627 }
4628 // Scan the tokens that are at the end of the cursor, but are not captured
4629 // but the child cursors.
4630 for (unsigned I = AfterChildren; I != Last; ++I)
4631 Cursors[I] = cursor;
4632
4633 TokIdx = Last;
4634 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004635}
4636
Ted Kremenek6db61092010-05-05 00:55:15 +00004637static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4638 CXCursor parent,
4639 CXClientData client_data) {
4640 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4641}
4642
Ted Kremenek6628a612011-03-18 22:51:30 +00004643namespace {
4644 struct clang_annotateTokens_Data {
4645 CXTranslationUnit TU;
4646 ASTUnit *CXXUnit;
4647 CXToken *Tokens;
4648 unsigned NumTokens;
4649 CXCursor *Cursors;
4650 };
4651}
4652
Ted Kremenekab979612010-11-11 08:05:23 +00004653// This gets run a separate thread to avoid stack blowout.
Ted Kremenek6628a612011-03-18 22:51:30 +00004654static void clang_annotateTokensImpl(void *UserData) {
4655 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4656 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4657 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4658 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4659 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4660
4661 // Determine the region of interest, which contains all of the tokens.
4662 SourceRange RegionOfInterest;
4663 RegionOfInterest.setBegin(
4664 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4665 RegionOfInterest.setEnd(
4666 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4667 Tokens[NumTokens-1])));
4668
4669 // A mapping from the source locations found when re-lexing or traversing the
4670 // region of interest to the corresponding cursors.
4671 AnnotateTokensData Annotated;
4672
4673 // Relex the tokens within the source range to look for preprocessing
4674 // directives.
4675 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4676 std::pair<FileID, unsigned> BeginLocInfo
4677 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4678 std::pair<FileID, unsigned> EndLocInfo
4679 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4680
4681 llvm::StringRef Buffer;
4682 bool Invalid = false;
4683 if (BeginLocInfo.first == EndLocInfo.first &&
4684 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4685 !Invalid) {
4686 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4687 CXXUnit->getASTContext().getLangOptions(),
4688 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4689 Buffer.end());
4690 Lex.SetCommentRetentionState(true);
4691
4692 // Lex tokens in raw mode until we hit the end of the range, to avoid
4693 // entering #includes or expanding macros.
4694 while (true) {
4695 Token Tok;
4696 Lex.LexFromRawLexer(Tok);
4697
4698 reprocess:
4699 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4700 // We have found a preprocessing directive. Gobble it up so that we
4701 // don't see it while preprocessing these tokens later, but keep track
4702 // of all of the token locations inside this preprocessing directive so
4703 // that we can annotate them appropriately.
4704 //
4705 // FIXME: Some simple tests here could identify macro definitions and
4706 // #undefs, to provide specific cursor kinds for those.
4707 llvm::SmallVector<SourceLocation, 32> Locations;
4708 do {
4709 Locations.push_back(Tok.getLocation());
4710 Lex.LexFromRawLexer(Tok);
4711 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4712
4713 using namespace cxcursor;
4714 CXCursor Cursor
4715 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4716 Locations.back()),
4717 TU);
4718 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4719 Annotated[Locations[I].getRawEncoding()] = Cursor;
4720 }
4721
4722 if (Tok.isAtStartOfLine())
4723 goto reprocess;
4724
4725 continue;
4726 }
4727
4728 if (Tok.is(tok::eof))
4729 break;
4730 }
4731 }
4732
4733 // Annotate all of the source locations in the region of interest that map to
4734 // a specific cursor.
4735 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4736 TU, RegionOfInterest);
4737
4738 // FIXME: We use a ridiculous stack size here because the data-recursion
4739 // algorithm uses a large stack frame than the non-data recursive version,
4740 // and AnnotationTokensWorker currently transforms the data-recursion
4741 // algorithm back into a traditional recursion by explicitly calling
4742 // VisitChildren(). We will need to remove this explicit recursive call.
4743 W.AnnotateTokens();
4744
4745 // If we ran into any entities that involve context-sensitive keywords,
4746 // take another pass through the tokens to mark them as such.
4747 if (W.hasContextSensitiveKeywords()) {
4748 for (unsigned I = 0; I != NumTokens; ++I) {
4749 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4750 continue;
4751
4752 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4753 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4754 if (ObjCPropertyDecl *Property
4755 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4756 if (Property->getPropertyAttributesAsWritten() != 0 &&
4757 llvm::StringSwitch<bool>(II->getName())
4758 .Case("readonly", true)
4759 .Case("assign", true)
4760 .Case("readwrite", true)
4761 .Case("retain", true)
4762 .Case("copy", true)
4763 .Case("nonatomic", true)
4764 .Case("atomic", true)
4765 .Case("getter", true)
4766 .Case("setter", true)
4767 .Default(false))
4768 Tokens[I].int_data[0] = CXToken_Keyword;
4769 }
4770 continue;
4771 }
4772
4773 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4774 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4775 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4776 if (llvm::StringSwitch<bool>(II->getName())
4777 .Case("in", true)
4778 .Case("out", true)
4779 .Case("inout", true)
4780 .Case("oneway", true)
4781 .Case("bycopy", true)
4782 .Case("byref", true)
4783 .Default(false))
4784 Tokens[I].int_data[0] = CXToken_Keyword;
4785 continue;
4786 }
4787
4788 if (Cursors[I].kind == CXCursor_CXXMethod) {
4789 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4790 if (CXXMethodDecl *Method
4791 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4792 if ((Method->hasAttr<FinalAttr>() ||
4793 Method->hasAttr<OverrideAttr>()) &&
4794 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4795 llvm::StringSwitch<bool>(II->getName())
4796 .Case("final", true)
4797 .Case("override", true)
4798 .Default(false))
4799 Tokens[I].int_data[0] = CXToken_Keyword;
4800 }
4801 continue;
4802 }
4803
4804 if (Cursors[I].kind == CXCursor_ClassDecl ||
4805 Cursors[I].kind == CXCursor_StructDecl ||
4806 Cursors[I].kind == CXCursor_ClassTemplate) {
4807 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4808 if (II->getName() == "final") {
4809 // We have to be careful with 'final', since it could be the name
4810 // of a member class rather than the context-sensitive keyword.
4811 // So, check whether the cursor associated with this
4812 Decl *D = getCursorDecl(Cursors[I]);
4813 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4814 if ((Record->hasAttr<FinalAttr>()) &&
4815 Record->getIdentifier() != II)
4816 Tokens[I].int_data[0] = CXToken_Keyword;
4817 } else if (ClassTemplateDecl *ClassTemplate
4818 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4819 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4820 if ((Record->hasAttr<FinalAttr>()) &&
4821 Record->getIdentifier() != II)
4822 Tokens[I].int_data[0] = CXToken_Keyword;
4823 }
4824 }
4825 continue;
4826 }
4827 }
4828 }
Ted Kremenekab979612010-11-11 08:05:23 +00004829}
4830
Ted Kremenek6db61092010-05-05 00:55:15 +00004831extern "C" {
4832
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004833void clang_annotateTokens(CXTranslationUnit TU,
4834 CXToken *Tokens, unsigned NumTokens,
4835 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004836
4837 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004838 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004839
Douglas Gregor4419b672010-10-21 06:10:04 +00004840 // Any token we don't specifically annotate will have a NULL cursor.
4841 CXCursor C = clang_getNullCursor();
4842 for (unsigned I = 0; I != NumTokens; ++I)
4843 Cursors[I] = C;
4844
Ted Kremeneka60ed472010-11-16 08:15:36 +00004845 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004846 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004847 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004848
Douglas Gregorbdf60622010-03-05 21:16:25 +00004849 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek6628a612011-03-18 22:51:30 +00004850
4851 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekab979612010-11-11 08:05:23 +00004852 llvm::CrashRecoveryContext CRC;
Ted Kremenek6628a612011-03-18 22:51:30 +00004853 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004854 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004855 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4856 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004857}
Ted Kremenek6628a612011-03-18 22:51:30 +00004858
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004859} // end: extern "C"
4860
4861//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004862// Operations for querying linkage of a cursor.
4863//===----------------------------------------------------------------------===//
4864
4865extern "C" {
4866CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004867 if (!clang_isDeclaration(cursor.kind))
4868 return CXLinkage_Invalid;
4869
Ted Kremenek16b42592010-03-03 06:36:57 +00004870 Decl *D = cxcursor::getCursorDecl(cursor);
4871 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4872 switch (ND->getLinkage()) {
4873 case NoLinkage: return CXLinkage_NoLinkage;
4874 case InternalLinkage: return CXLinkage_Internal;
4875 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4876 case ExternalLinkage: return CXLinkage_External;
4877 };
4878
4879 return CXLinkage_Invalid;
4880}
4881} // end: extern "C"
4882
4883//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004884// Operations for querying language of a cursor.
4885//===----------------------------------------------------------------------===//
4886
4887static CXLanguageKind getDeclLanguage(const Decl *D) {
4888 switch (D->getKind()) {
4889 default:
4890 break;
4891 case Decl::ImplicitParam:
4892 case Decl::ObjCAtDefsField:
4893 case Decl::ObjCCategory:
4894 case Decl::ObjCCategoryImpl:
4895 case Decl::ObjCClass:
4896 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004897 case Decl::ObjCForwardProtocol:
4898 case Decl::ObjCImplementation:
4899 case Decl::ObjCInterface:
4900 case Decl::ObjCIvar:
4901 case Decl::ObjCMethod:
4902 case Decl::ObjCProperty:
4903 case Decl::ObjCPropertyImpl:
4904 case Decl::ObjCProtocol:
4905 return CXLanguage_ObjC;
4906 case Decl::CXXConstructor:
4907 case Decl::CXXConversion:
4908 case Decl::CXXDestructor:
4909 case Decl::CXXMethod:
4910 case Decl::CXXRecord:
4911 case Decl::ClassTemplate:
4912 case Decl::ClassTemplatePartialSpecialization:
4913 case Decl::ClassTemplateSpecialization:
4914 case Decl::Friend:
4915 case Decl::FriendTemplate:
4916 case Decl::FunctionTemplate:
4917 case Decl::LinkageSpec:
4918 case Decl::Namespace:
4919 case Decl::NamespaceAlias:
4920 case Decl::NonTypeTemplateParm:
4921 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004922 case Decl::TemplateTemplateParm:
4923 case Decl::TemplateTypeParm:
4924 case Decl::UnresolvedUsingTypename:
4925 case Decl::UnresolvedUsingValue:
4926 case Decl::Using:
4927 case Decl::UsingDirective:
4928 case Decl::UsingShadow:
4929 return CXLanguage_CPlusPlus;
4930 }
4931
4932 return CXLanguage_C;
4933}
4934
4935extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004936
4937enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4938 if (clang_isDeclaration(cursor.kind))
4939 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004940 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregor58ddb602010-08-23 23:00:57 +00004941 return CXAvailability_Available;
4942
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004943 switch (D->getAvailability()) {
4944 case AR_Available:
4945 case AR_NotYetIntroduced:
4946 return CXAvailability_Available;
4947
4948 case AR_Deprecated:
Douglas Gregor58ddb602010-08-23 23:00:57 +00004949 return CXAvailability_Deprecated;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004950
4951 case AR_Unavailable:
4952 return CXAvailability_NotAvailable;
4953 }
Douglas Gregor58ddb602010-08-23 23:00:57 +00004954 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004955
Douglas Gregor58ddb602010-08-23 23:00:57 +00004956 return CXAvailability_Available;
4957}
4958
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004959CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4960 if (clang_isDeclaration(cursor.kind))
4961 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4962
4963 return CXLanguage_Invalid;
4964}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004965
4966 /// \brief If the given cursor is the "templated" declaration
4967 /// descibing a class or function template, return the class or
4968 /// function template.
4969static Decl *maybeGetTemplateCursor(Decl *D) {
4970 if (!D)
4971 return 0;
4972
4973 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4974 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4975 return FunTmpl;
4976
4977 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4978 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4979 return ClassTmpl;
4980
4981 return D;
4982}
4983
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004984CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4985 if (clang_isDeclaration(cursor.kind)) {
4986 if (Decl *D = getCursorDecl(cursor)) {
4987 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004988 if (!DC)
4989 return clang_getNullCursor();
4990
4991 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4992 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004993 }
4994 }
4995
4996 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4997 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004998 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004999 }
5000
5001 return clang_getNullCursor();
5002}
5003
5004CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5005 if (clang_isDeclaration(cursor.kind)) {
5006 if (Decl *D = getCursorDecl(cursor)) {
5007 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00005008 if (!DC)
5009 return clang_getNullCursor();
5010
5011 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5012 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005013 }
5014 }
5015
5016 // FIXME: Note that we can't easily compute the lexical context of a
5017 // statement or expression, so we return nothing.
5018 return clang_getNullCursor();
5019}
5020
Douglas Gregor9f592342010-10-01 20:25:15 +00005021static void CollectOverriddenMethods(DeclContext *Ctx,
5022 ObjCMethodDecl *Method,
5023 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5024 if (!Ctx)
5025 return;
5026
5027 // If we have a class or category implementation, jump straight to the
5028 // interface.
5029 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5030 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5031
5032 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5033 if (!Container)
5034 return;
5035
5036 // Check whether we have a matching method at this level.
5037 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5038 Method->isInstanceMethod()))
5039 if (Method != Overridden) {
5040 // We found an override at this level; there is no need to look
5041 // into other protocols or categories.
5042 Methods.push_back(Overridden);
5043 return;
5044 }
5045
5046 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5047 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5048 PEnd = Protocol->protocol_end();
5049 P != PEnd; ++P)
5050 CollectOverriddenMethods(*P, Method, Methods);
5051 }
5052
5053 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5054 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5055 PEnd = Category->protocol_end();
5056 P != PEnd; ++P)
5057 CollectOverriddenMethods(*P, Method, Methods);
5058 }
5059
5060 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5061 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5062 PEnd = Interface->protocol_end();
5063 P != PEnd; ++P)
5064 CollectOverriddenMethods(*P, Method, Methods);
5065
5066 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5067 Category; Category = Category->getNextClassCategory())
5068 CollectOverriddenMethods(Category, Method, Methods);
5069
5070 // We only look into the superclass if we haven't found anything yet.
5071 if (Methods.empty())
5072 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5073 return CollectOverriddenMethods(Super, Method, Methods);
5074 }
5075}
5076
5077void clang_getOverriddenCursors(CXCursor cursor,
5078 CXCursor **overridden,
5079 unsigned *num_overridden) {
5080 if (overridden)
5081 *overridden = 0;
5082 if (num_overridden)
5083 *num_overridden = 0;
5084 if (!overridden || !num_overridden)
5085 return;
5086
5087 if (!clang_isDeclaration(cursor.kind))
5088 return;
5089
5090 Decl *D = getCursorDecl(cursor);
5091 if (!D)
5092 return;
5093
5094 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00005095 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00005096 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5097 *num_overridden = CXXMethod->size_overridden_methods();
5098 if (!*num_overridden)
5099 return;
5100
5101 *overridden = new CXCursor [*num_overridden];
5102 unsigned I = 0;
5103 for (CXXMethodDecl::method_iterator
5104 M = CXXMethod->begin_overridden_methods(),
5105 MEnd = CXXMethod->end_overridden_methods();
5106 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005107 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005108 return;
5109 }
5110
5111 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5112 if (!Method)
5113 return;
5114
5115 // Handle Objective-C methods.
5116 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5117 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5118
5119 if (Methods.empty())
5120 return;
5121
5122 *num_overridden = Methods.size();
5123 *overridden = new CXCursor [Methods.size()];
5124 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005125 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005126}
5127
5128void clang_disposeOverriddenCursors(CXCursor *overridden) {
5129 delete [] overridden;
5130}
5131
Douglas Gregorecdcb882010-10-20 22:00:55 +00005132CXFile clang_getIncludedFile(CXCursor cursor) {
5133 if (cursor.kind != CXCursor_InclusionDirective)
5134 return 0;
5135
5136 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5137 return (void *)ID->getFile();
5138}
5139
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005140} // end: extern "C"
5141
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005142
5143//===----------------------------------------------------------------------===//
5144// C++ AST instrospection.
5145//===----------------------------------------------------------------------===//
5146
5147extern "C" {
5148unsigned clang_CXXMethod_isStatic(CXCursor C) {
5149 if (!clang_isDeclaration(C.kind))
5150 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005151
5152 CXXMethodDecl *Method = 0;
5153 Decl *D = cxcursor::getCursorDecl(C);
5154 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5155 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5156 else
5157 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5158 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005159}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005160
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005161} // end: extern "C"
5162
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005163//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005164// Attribute introspection.
5165//===----------------------------------------------------------------------===//
5166
5167extern "C" {
5168CXType clang_getIBOutletCollectionType(CXCursor C) {
5169 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005170 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005171
5172 IBOutletCollectionAttr *A =
5173 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5174
Douglas Gregor841b2382011-03-06 18:55:32 +00005175 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005176}
5177} // end: extern "C"
5178
5179//===----------------------------------------------------------------------===//
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005180// Inspecting memory usage.
5181//===----------------------------------------------------------------------===//
5182
5183typedef std::vector<CXTUMemoryUsageEntry> MemUsageEntries;
5184
5185static inline void createCXTUMemoryUsageEntry(MemUsageEntries &entries,
5186 enum CXTUMemoryUsageKind k,
5187 double amount) {
5188 CXTUMemoryUsageEntry entry = { k, amount };
5189 entries.push_back(entry);
5190}
5191
5192extern "C" {
5193
5194const char *clang_getTUMemoryUsageName(CXTUMemoryUsageKind kind) {
5195 const char *str = "";
5196 switch (kind) {
5197 case CXTUMemoryUsage_AST:
5198 str = "ASTContext: expressions, declarations, and types";
5199 break;
5200 case CXTUMemoryUsage_Identifiers:
5201 str = "ASTContext: identifiers";
5202 break;
5203 case CXTUMemoryUsage_Selectors:
5204 str = "ASTContext: selectors";
5205 }
5206 return str;
5207}
5208
5209CXTUMemoryUsage clang_getCXTUMemoryUsage(CXTranslationUnit TU) {
5210 if (!TU) {
5211 CXTUMemoryUsage usage = { (void*) 0, 0, 0 };
5212 return usage;
5213 }
5214
5215 ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
5216 llvm::OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
5217 ASTContext &astContext = astUnit->getASTContext();
5218
5219 // How much memory is used by AST nodes and types?
5220 createCXTUMemoryUsageEntry(*entries, CXTUMemoryUsage_AST,
5221 (unsigned long) astContext.getTotalAllocatedMemory());
5222
5223 // How much memory is used by identifiers?
5224 createCXTUMemoryUsageEntry(*entries, CXTUMemoryUsage_Identifiers,
5225 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
5226
5227 // How much memory is used for selectors?
5228 createCXTUMemoryUsageEntry(*entries, CXTUMemoryUsage_Selectors,
5229 (unsigned long) astContext.Selectors.getTotalMemory());
5230
5231 CXTUMemoryUsage usage = { (void*) entries.get(),
5232 (unsigned) entries->size(),
5233 entries->size() ? &(*entries)[0] : 0 };
5234 entries.take();
5235 return usage;
5236}
5237
5238void clang_disposeCXTUMemoryUsage(CXTUMemoryUsage usage) {
5239 if (usage.data)
5240 delete (MemUsageEntries*) usage.data;
5241}
5242
5243} // end extern "C"
5244
5245//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005246// Misc. utility functions.
5247//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005248
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005249/// Default to using an 8 MB stack size on "safety" threads.
5250static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005251
5252namespace clang {
5253
5254bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005255 void (*Fn)(void*), void *UserData,
5256 unsigned Size) {
5257 if (!Size)
5258 Size = GetSafetyThreadStackSize();
5259 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005260 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5261 return CRC.RunSafely(Fn, UserData);
5262}
5263
5264unsigned GetSafetyThreadStackSize() {
5265 return SafetyStackThreadSize;
5266}
5267
5268void SetSafetyThreadStackSize(unsigned Value) {
5269 SafetyStackThreadSize = Value;
5270}
5271
5272}
5273
Ted Kremenek04bb7162010-01-22 22:44:15 +00005274extern "C" {
5275
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005276CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005277 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005278}
5279
5280} // end: extern "C"
Ted Kremenek59fc1e52011-04-18 22:47:10 +00005281