blob: 80fc7551d7f7717cc5593ecb1b529df42738a828 [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
Ted Kremenek09dfa372010-02-18 05:46:33 +0000275 bool VisitAttributes(Decl *D);
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000276 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenek3064ef92010-08-27 21:34:58 +0000277 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000278 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000279 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000280 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
281 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000282 bool VisitTagDecl(TagDecl *D);
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000283 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregor74dbe642010-08-31 19:31:58 +0000284 bool VisitClassTemplatePartialSpecializationDecl(
285 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000286 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000287 bool VisitEnumConstantDecl(EnumConstantDecl *D);
288 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
289 bool VisitFunctionDecl(FunctionDecl *ND);
290 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000291 bool VisitVarDecl(VarDecl *);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000292 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000293 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor39d6f072010-08-31 19:02:00 +0000294 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000295 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000296 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
297 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
298 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
299 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek23173d72010-05-18 21:09:07 +0000300 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremenek79758f62010-02-18 22:36:18 +0000301 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
302 bool VisitObjCImplDecl(ObjCImplDecl *D);
303 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
304 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000305 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
306 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
307 bool VisitObjCClassDecl(ObjCClassDecl *D);
Douglas Gregora4ffd852010-11-17 01:03:52 +0000308 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
Ted Kremeneka0536d82010-05-07 01:04:29 +0000309 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenek8f06e0e2010-05-06 23:38:21 +0000310 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregor69319002010-08-31 23:48:11 +0000311 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000312 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregor7e242562010-09-01 19:52:22 +0000313 bool VisitUsingDecl(UsingDecl *D);
314 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
315 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000316
Douglas Gregor01829d32010-08-31 14:41:23 +0000317 // Name visitor
318 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000319 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregordc355712011-02-25 00:36:19 +0000320 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
Douglas Gregor01829d32010-08-31 14:41:23 +0000321
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000322 // Template visitors
323 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregor0b36e612010-08-31 20:37:03 +0000324 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000325 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
326
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000327 // Type visitors
Douglas Gregor01829d32010-08-31 14:41:23 +0000328 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000329 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000330 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000331 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
332 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000333 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000334 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCallc12c5bb2010-05-15 11:32:37 +0000335 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000336 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
Abramo Bagnara075f8f12010-12-10 16:29:40 +0000337 bool VisitParenTypeLoc(ParenTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000338 bool VisitPointerTypeLoc(PointerTypeLoc TL);
339 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
340 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
341 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
342 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor01829d32010-08-31 14:41:23 +0000343 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000344 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000345 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000346 // FIXME: Implement visitors here when the unimplemented TypeLocs get
347 // implemented
348 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
Douglas Gregor7536dd52010-12-20 02:24:11 +0000349 bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000350 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000351 bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
Douglas Gregor94fdffa2011-03-01 20:11:18 +0000352 bool VisitDependentTemplateSpecializationTypeLoc(
353 DependentTemplateSpecializationTypeLoc TL);
Douglas Gregor9e876872011-03-01 18:12:44 +0000354 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000355
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000356 // Data-recursive visitor functions.
357 bool IsInRegionOfInterest(CXCursor C);
358 bool RunVisitorWorkList(VisitorWorkList &WL);
359 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
Ted Kremenekcdba6592010-11-18 00:42:18 +0000360 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
Steve Naroff89922f82009-08-31 00:59:03 +0000361};
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000362
Ted Kremenekab188932010-01-05 19:32:54 +0000363} // end anonymous namespace
Benjamin Kramer5e4bc592009-10-18 16:11:04 +0000364
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000365static SourceRange getRawCursorExtent(CXCursor C);
Douglas Gregor66537982010-11-17 17:14:07 +0000366static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
367
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000368
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000369RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000370 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000371}
372
Douglas Gregorb1373d02010-01-20 20:59:29 +0000373/// \brief Visit the given cursor and, if requested by the visitor,
374/// its children.
375///
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000376/// \param Cursor the cursor to visit.
377///
378/// \param CheckRegionOfInterest if true, then the caller already checked that
379/// this cursor is within the region of interest.
380///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000381/// \returns true if the visitation should be aborted, false if it
382/// should continue.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000383bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregorb1373d02010-01-20 20:59:29 +0000384 if (clang_isInvalid(Cursor.kind))
385 return false;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000386
Douglas Gregorb1373d02010-01-20 20:59:29 +0000387 if (clang_isDeclaration(Cursor.kind)) {
388 Decl *D = getCursorDecl(Cursor);
389 assert(D && "Invalid declaration cursor");
390 if (D->getPCHLevel() > MaxPCHLevel)
391 return false;
392
393 if (D->isImplicit())
394 return false;
395 }
396
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000397 // If we have a range of interest, and this cursor doesn't intersect with it,
398 // we're done.
399 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000400 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbarf408f322010-02-14 08:32:05 +0000401 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000402 return false;
403 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000404
Douglas Gregorb1373d02010-01-20 20:59:29 +0000405 switch (Visitor(Cursor, Parent, ClientData)) {
406 case CXChildVisit_Break:
407 return true;
408
409 case CXChildVisit_Continue:
410 return false;
411
412 case CXChildVisit_Recurse:
413 return VisitChildren(Cursor);
414 }
415
Douglas Gregorfd643772010-01-25 16:45:46 +0000416 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000417}
418
Douglas Gregor788f5a12010-03-20 00:41:21 +0000419std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
420CursorVisitor::getPreprocessedEntities() {
421 PreprocessingRecord &PPRec
Ted Kremeneka60ed472010-11-16 08:15:36 +0000422 = *AU->getPreprocessor().getPreprocessingRecord();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000423
424 bool OnlyLocalDecls
Douglas Gregor32038bb2010-12-21 19:07:48 +0000425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls && RegionOfInterest.isValid()) {
428 // If we would only look at local declarations but we have a region of
429 // interest, check whether that region of interest is in the main file.
430 // If not, we should traverse all declarations.
431 // FIXME: My kingdom for a proper binary search approach to finding
432 // cursors!
433 std::pair<FileID, unsigned> Location
434 = AU->getSourceManager().getDecomposedInstantiationLoc(
435 RegionOfInterest.getBegin());
436 if (Location.first != AU->getSourceManager().getMainFileID())
437 OnlyLocalDecls = false;
438 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000439
Douglas Gregor89d99802010-11-30 06:16:57 +0000440 PreprocessingRecord::iterator StartEntity, EndEntity;
441 if (OnlyLocalDecls) {
442 StartEntity = AU->pp_entity_begin();
443 EndEntity = AU->pp_entity_end();
444 } else {
445 StartEntity = PPRec.begin();
446 EndEntity = PPRec.end();
447 }
448
Douglas Gregor788f5a12010-03-20 00:41:21 +0000449 // There is no region of interest; we have to walk everything.
450 if (RegionOfInterest.isInvalid())
Douglas Gregor89d99802010-11-30 06:16:57 +0000451 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000452
453 // Find the file in which the region of interest lands.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000454 SourceManager &SM = AU->getSourceManager();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000455 std::pair<FileID, unsigned> Begin
456 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
457 std::pair<FileID, unsigned> End
458 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
459
460 // The region of interest spans files; we have to walk everything.
461 if (Begin.first != End.first)
Douglas Gregor89d99802010-11-30 06:16:57 +0000462 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000463
464 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
Ted Kremeneka60ed472010-11-16 08:15:36 +0000465 = AU->getPreprocessedEntitiesByFile();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000466 if (ByFileMap.empty()) {
467 // Build the mapping from files to sets of preprocessed entities.
Douglas Gregor89d99802010-11-30 06:16:57 +0000468 for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
Douglas Gregor788f5a12010-03-20 00:41:21 +0000469 std::pair<FileID, unsigned> P
470 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
Douglas Gregor89d99802010-11-30 06:16:57 +0000471
Douglas Gregor788f5a12010-03-20 00:41:21 +0000472 ByFileMap[P.first].push_back(*E);
473 }
474 }
475
476 return std::make_pair(ByFileMap[Begin.first].begin(),
477 ByFileMap[Begin.first].end());
478}
479
Douglas Gregorb1373d02010-01-20 20:59:29 +0000480/// \brief Visit the children of the given cursor.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000481///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregorc314aa42011-03-02 19:17:03 +0000485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
Douglas Gregora59e3902010-01-21 23:27:09 +0000487 // By definition, references have no children.
488 return false;
489 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000490
491 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregorb1373d02010-01-20 20:59:29 +0000492 // done.
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000494
Douglas Gregorb1373d02010-01-20 20:59:29 +0000495 if (clang_isDeclaration(Cursor.kind)) {
496 Decl *D = getCursorDecl(Cursor);
497 assert(D && "Invalid declaration cursor");
Ted Kremenek539311e2010-02-18 18:47:01 +0000498 return VisitAttributes(D) || Visit(D);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000499 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000500
Douglas Gregora59e3902010-01-21 23:27:09 +0000501 if (clang_isStatement(Cursor.kind))
502 return Visit(getCursorStmt(Cursor));
503 if (clang_isExpression(Cursor.kind))
504 return Visit(getCursorExpr(Cursor));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000505
Douglas Gregorb1373d02010-01-20 20:59:29 +0000506 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000507 CXTranslationUnit tu = getCursorTU(Cursor);
508 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000509
510 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
511 for (unsigned I = 0; I != 2; ++I) {
512 if (VisitOrder[I]) {
513 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
514 RegionOfInterest.isInvalid()) {
515 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
516 TLEnd = CXXUnit->top_level_end();
517 TL != TLEnd; ++TL) {
518 if (Visit(MakeCXCursor(*TL, tu), true))
519 return true;
520 }
521 } else if (VisitDeclContext(
522 CXXUnit->getASTContext().getTranslationUnitDecl()))
Douglas Gregor7b691f332010-01-20 21:13:59 +0000523 return true;
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000524 continue;
Douglas Gregor7b691f332010-01-20 21:13:59 +0000525 }
Bob Wilson3178cb62010-03-19 03:57:57 +0000526
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000527 // Walk the preprocessing record.
528 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
529 // FIXME: Once we have the ability to deserialize a preprocessing record,
530 // do so.
531 PreprocessingRecord::iterator E, EEnd;
532 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
533 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
534 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
535 return true;
536
537 continue;
538 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000539
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000540 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
541 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
542 return true;
543
544 continue;
545 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000546
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000547 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
548 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
549 return true;
550
551 continue;
552 }
Douglas Gregorecdcb882010-10-20 22:00:55 +0000553 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000554 }
555 }
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000556
Douglas Gregor7b691f332010-01-20 21:13:59 +0000557 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000558 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000559
Douglas Gregorc314aa42011-03-02 19:17:03 +0000560 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
561 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
562 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
563 return Visit(BaseTSInfo->getTypeLoc());
564 }
565 }
566 }
567
Douglas Gregorb1373d02010-01-20 20:59:29 +0000568 // Nothing to visit at the moment.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000569 return false;
570}
571
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000572bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
John McCallfc929202010-06-04 22:33:30 +0000573 if (Visit(B->getSignatureAsWritten()->getTypeLoc()))
574 return true;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000575
Ted Kremenek664cffd2010-07-22 11:30:19 +0000576 if (Stmt *Body = B->getBody())
577 return Visit(MakeCXCursor(Body, StmtParent, TU));
578
579 return false;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000580}
581
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000582llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
583 if (RegionOfInterest.isValid()) {
Douglas Gregor66537982010-11-17 17:14:07 +0000584 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000585 if (Range.isInvalid())
586 return llvm::Optional<bool>();
Douglas Gregor66537982010-11-17 17:14:07 +0000587
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000588 switch (CompareRegionOfInterest(Range)) {
589 case RangeBefore:
590 // This declaration comes before the region of interest; skip it.
591 return llvm::Optional<bool>();
592
593 case RangeAfter:
594 // This declaration comes after the region of interest; we're done.
595 return false;
596
597 case RangeOverlap:
598 // This declaration overlaps the region of interest; visit it.
599 break;
600 }
601 }
602 return true;
603}
604
605bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
606 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
607
608 // FIXME: Eventually remove. This part of a hack to support proper
609 // iteration over all Decls contained lexically within an ObjC container.
610 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
611 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
612
613 for ( ; I != E; ++I) {
Ted Kremenek23173d72010-05-18 21:09:07 +0000614 Decl *D = *I;
615 if (D->getLexicalDeclContext() != DC)
616 continue;
Ted Kremenek23173d72010-05-18 21:09:07 +0000617 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000618 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
619 if (!V.hasValue())
620 continue;
621 if (!V.getValue())
622 return false;
Daniel Dunbard52864b2010-02-14 10:02:57 +0000623 if (Visit(Cursor, true))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000624 return true;
625 }
Douglas Gregorb1373d02010-01-20 20:59:29 +0000626 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000627}
628
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000629bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
630 llvm_unreachable("Translation units are visited directly by Visit()");
631 return false;
632}
633
634bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
635 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
636 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000637
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000638 return false;
639}
640
641bool CursorVisitor::VisitTagDecl(TagDecl *D) {
642 return VisitDeclContext(D);
643}
644
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000645bool CursorVisitor::VisitClassTemplateSpecializationDecl(
646 ClassTemplateSpecializationDecl *D) {
647 bool ShouldVisitBody = false;
648 switch (D->getSpecializationKind()) {
649 case TSK_Undeclared:
650 case TSK_ImplicitInstantiation:
651 // Nothing to visit
652 return false;
653
654 case TSK_ExplicitInstantiationDeclaration:
655 case TSK_ExplicitInstantiationDefinition:
656 break;
657
658 case TSK_ExplicitSpecialization:
659 ShouldVisitBody = true;
660 break;
661 }
662
663 // Visit the template arguments used in the specialization.
664 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
665 TypeLoc TL = SpecType->getTypeLoc();
666 if (TemplateSpecializationTypeLoc *TSTLoc
667 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
668 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
669 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
670 return true;
671 }
672 }
673
674 if (ShouldVisitBody && VisitCXXRecordDecl(D))
675 return true;
676
677 return false;
678}
679
Douglas Gregor74dbe642010-08-31 19:31:58 +0000680bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
681 ClassTemplatePartialSpecializationDecl *D) {
682 // FIXME: Visit the "outer" template parameter lists on the TagDecl
683 // before visiting these template parameters.
684 if (VisitTemplateParameters(D->getTemplateParameters()))
685 return true;
686
687 // Visit the partial specialization arguments.
688 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
689 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
690 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
691 return true;
692
693 return VisitCXXRecordDecl(D);
694}
695
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000696bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor84b51d72010-09-01 20:16:53 +0000697 // Visit the default argument.
698 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
699 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
700 if (Visit(DefArg->getTypeLoc()))
701 return true;
702
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000703 return false;
704}
705
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000706bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
707 if (Expr *Init = D->getInitExpr())
708 return Visit(MakeCXCursor(Init, StmtParent, TU));
709 return false;
710}
711
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000712bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
713 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
714 if (Visit(TSInfo->getTypeLoc()))
715 return true;
716
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000717 // Visit the nested-name-specifier, if present.
718 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
719 if (VisitNestedNameSpecifierLoc(QualifierLoc))
720 return true;
721
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000722 return false;
723}
724
Douglas Gregora67e03f2010-09-09 21:42:20 +0000725/// \brief Compare two base or member initializers based on their source order.
Sean Huntcbb67482011-01-08 20:30:50 +0000726static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
727 CXXCtorInitializer const * const *X
728 = static_cast<CXXCtorInitializer const * const *>(Xp);
729 CXXCtorInitializer const * const *Y
730 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000731
732 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
733 return -1;
734 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
735 return 1;
736 else
737 return 0;
738}
739
Douglas Gregorb1373d02010-01-20 20:59:29 +0000740bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor01829d32010-08-31 14:41:23 +0000741 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
742 // Visit the function declaration's syntactic components in the order
743 // written. This requires a bit of work.
Abramo Bagnara723df242010-12-14 22:11:44 +0000744 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor01829d32010-08-31 14:41:23 +0000745 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
746
747 // If we have a function declared directly (without the use of a typedef),
748 // visit just the return type. Otherwise, just visit the function's type
749 // now.
750 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
751 (!FTL && Visit(TL)))
752 return true;
753
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000754 // Visit the nested-name-specifier, if present.
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000755 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
756 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000757 return true;
Douglas Gregor01829d32010-08-31 14:41:23 +0000758
759 // Visit the declaration name.
760 if (VisitDeclarationNameInfo(ND->getNameInfo()))
761 return true;
762
763 // FIXME: Visit explicitly-specified template arguments!
764
765 // Visit the function parameters, if we have a function type.
766 if (FTL && VisitFunctionTypeLoc(*FTL, true))
767 return true;
768
769 // FIXME: Attributes?
770 }
771
Douglas Gregora67e03f2010-09-09 21:42:20 +0000772 if (ND->isThisDeclarationADefinition()) {
773 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
774 // Find the initializers that were written in the source.
Sean Huntcbb67482011-01-08 20:30:50 +0000775 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregora67e03f2010-09-09 21:42:20 +0000776 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
777 IEnd = Constructor->init_end();
778 I != IEnd; ++I) {
779 if (!(*I)->isWritten())
780 continue;
781
782 WrittenInits.push_back(*I);
783 }
784
785 // Sort the initializers in source order
786 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Sean Huntcbb67482011-01-08 20:30:50 +0000787 &CompareCXXCtorInitializers);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000788
789 // Visit the initializers in source order
790 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Sean Huntcbb67482011-01-08 20:30:50 +0000791 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichet00eb3f92010-12-04 09:14:42 +0000792 if (Init->isAnyMemberInitializer()) {
793 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregora67e03f2010-09-09 21:42:20 +0000794 Init->getMemberLocation(), TU)))
795 return true;
796 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
797 if (Visit(BaseInfo->getTypeLoc()))
798 return true;
799 }
800
801 // Visit the initializer value.
802 if (Expr *Initializer = Init->getInit())
803 if (Visit(MakeCXCursor(Initializer, ND, TU)))
804 return true;
805 }
806 }
807
808 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
809 return true;
810 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000811
Douglas Gregorb1373d02010-01-20 20:59:29 +0000812 return false;
813}
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000814
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000815bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
816 if (VisitDeclaratorDecl(D))
817 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000818
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000819 if (Expr *BitWidth = D->getBitWidth())
820 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000821
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000822 return false;
823}
824
825bool CursorVisitor::VisitVarDecl(VarDecl *D) {
826 if (VisitDeclaratorDecl(D))
827 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000828
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000829 if (Expr *Init = D->getInit())
830 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000831
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000832 return false;
833}
834
Douglas Gregor84b51d72010-09-01 20:16:53 +0000835bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
836 if (VisitDeclaratorDecl(D))
837 return true;
838
839 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
840 if (Expr *DefArg = D->getDefaultArgument())
841 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
842
843 return false;
844}
845
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000846bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
847 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
848 // before visiting these template parameters.
849 if (VisitTemplateParameters(D->getTemplateParameters()))
850 return true;
851
852 return VisitFunctionDecl(D->getTemplatedDecl());
853}
854
Douglas Gregor39d6f072010-08-31 19:02:00 +0000855bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
856 // FIXME: Visit the "outer" template parameter lists on the TagDecl
857 // before visiting these template parameters.
858 if (VisitTemplateParameters(D->getTemplateParameters()))
859 return true;
860
861 return VisitCXXRecordDecl(D->getTemplatedDecl());
862}
863
Douglas Gregor84b51d72010-09-01 20:16:53 +0000864bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
865 if (VisitTemplateParameters(D->getTemplateParameters()))
866 return true;
867
868 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
869 VisitTemplateArgumentLoc(D->getDefaultArgument()))
870 return true;
871
872 return false;
873}
874
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000875bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor4bc1cb62010-03-08 14:59:44 +0000876 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
877 if (Visit(TSInfo->getTypeLoc()))
878 return true;
879
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000880 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000881 PEnd = ND->param_end();
882 P != PEnd; ++P) {
883 if (Visit(MakeCXCursor(*P, TU)))
884 return true;
885 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000886
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000887 if (ND->isThisDeclarationADefinition() &&
888 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
889 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000890
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000891 return false;
892}
893
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000894namespace {
895 struct ContainerDeclsSort {
896 SourceManager &SM;
897 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
898 bool operator()(Decl *A, Decl *B) {
899 SourceLocation L_A = A->getLocStart();
900 SourceLocation L_B = B->getLocStart();
901 assert(L_A.isValid() && L_B.isValid());
902 return SM.isBeforeInTranslationUnit(L_A, L_B);
903 }
904 };
905}
906
Douglas Gregora59e3902010-01-21 23:27:09 +0000907bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000908 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
909 // an @implementation can lexically contain Decls that are not properly
910 // nested in the AST. When we identify such cases, we need to retrofit
911 // this nesting here.
912 if (!DI_current)
913 return VisitDeclContext(D);
914
915 // Scan the Decls that immediately come after the container
916 // in the current DeclContext. If any fall within the
917 // container's lexical region, stash them into a vector
918 // for later processing.
919 llvm::SmallVector<Decl *, 24> DeclsInContainer;
920 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000921 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000922 if (EndLoc.isValid()) {
923 DeclContext::decl_iterator next = *DI_current;
924 while (++next != DE_current) {
925 Decl *D_next = *next;
926 if (!D_next)
927 break;
928 SourceLocation L = D_next->getLocStart();
929 if (!L.isValid())
930 break;
931 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
932 *DI_current = next;
933 DeclsInContainer.push_back(D_next);
934 continue;
935 }
936 break;
937 }
938 }
939
940 // The common case.
941 if (DeclsInContainer.empty())
942 return VisitDeclContext(D);
943
944 // Get all the Decls in the DeclContext, and sort them with the
945 // additional ones we've collected. Then visit them.
946 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
947 I!=E; ++I) {
948 Decl *subDecl = *I;
Ted Kremenek0582c892010-11-02 23:17:51 +0000949 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
950 subDecl->getLocStart().isInvalid())
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000951 continue;
952 DeclsInContainer.push_back(subDecl);
953 }
954
955 // Now sort the Decls so that they appear in lexical order.
956 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
957 ContainerDeclsSort(SM));
958
959 // Now visit the decls.
960 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
961 E = DeclsInContainer.end(); I != E; ++I) {
962 CXCursor Cursor = MakeCXCursor(*I, TU);
963 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
964 if (!V.hasValue())
965 continue;
966 if (!V.getValue())
967 return false;
968 if (Visit(Cursor, true))
969 return true;
970 }
971 return false;
Douglas Gregora59e3902010-01-21 23:27:09 +0000972}
973
Douglas Gregorb1373d02010-01-20 20:59:29 +0000974bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000975 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
976 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000977 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000978
Douglas Gregor78db0cd2010-01-16 15:44:18 +0000979 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
980 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
981 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000982 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000983 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000984
Douglas Gregora59e3902010-01-21 23:27:09 +0000985 return VisitObjCContainerDecl(ND);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000986}
987
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000988bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
989 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
990 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
991 E = PID->protocol_end(); I != E; ++I, ++PL)
992 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
993 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000994
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000995 return VisitObjCContainerDecl(PID);
996}
997
Ted Kremenek23173d72010-05-18 21:09:07 +0000998bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor83cb9422010-09-09 17:09:21 +0000999 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCallfc929202010-06-04 22:33:30 +00001000 return true;
1001
Ted Kremenek23173d72010-05-18 21:09:07 +00001002 // FIXME: This implements a workaround with @property declarations also being
1003 // installed in the DeclContext for the @interface. Eventually this code
1004 // should be removed.
1005 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1006 if (!CDecl || !CDecl->IsClassExtension())
1007 return false;
1008
1009 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1010 if (!ID)
1011 return false;
1012
1013 IdentifierInfo *PropertyId = PD->getIdentifier();
1014 ObjCPropertyDecl *prevDecl =
1015 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1016
1017 if (!prevDecl)
1018 return false;
1019
1020 // Visit synthesized methods since they will be skipped when visiting
1021 // the @interface.
1022 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001023 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001024 if (Visit(MakeCXCursor(MD, TU)))
1025 return true;
1026
1027 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001028 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001029 if (Visit(MakeCXCursor(MD, TU)))
1030 return true;
1031
1032 return false;
1033}
1034
Douglas Gregorb1373d02010-01-20 20:59:29 +00001035bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001036 // Issue callbacks for super class.
Douglas Gregorb1373d02010-01-20 20:59:29 +00001037 if (D->getSuperClass() &&
1038 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001039 D->getSuperClassLoc(),
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001040 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001041 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001042
Douglas Gregor78db0cd2010-01-16 15:44:18 +00001043 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1044 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1045 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001046 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001047 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001048
Douglas Gregora59e3902010-01-21 23:27:09 +00001049 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001050}
1051
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001052bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1053 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001054}
1055
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001056bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremenekebfa3392010-03-19 20:39:03 +00001057 // 'ID' could be null when dealing with invalid code.
1058 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1059 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1060 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001061
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001062 return VisitObjCImplDecl(D);
1063}
1064
1065bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1066#if 0
1067 // Issue callbacks for super class.
1068 // FIXME: No source location information!
1069 if (D->getSuperClass() &&
1070 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001071 D->getSuperClassLoc(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001072 TU)))
1073 return true;
1074#endif
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001075
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001076 return VisitObjCImplDecl(D);
1077}
1078
1079bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1080 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1081 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1082 E = D->protocol_end();
1083 I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001084 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001085 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001086
1087 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001088}
1089
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001090bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1091 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1092 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1093 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001094
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001095 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001096}
1097
Douglas Gregora4ffd852010-11-17 01:03:52 +00001098bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1099 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1100 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1101
1102 return false;
1103}
1104
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00001105bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1106 return VisitDeclContext(D);
1107}
1108
Douglas Gregor69319002010-08-31 23:48:11 +00001109bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001110 // Visit nested-name-specifier.
Douglas Gregor0cfaf6a2011-02-25 17:08:07 +00001111 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1112 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001113 return true;
Douglas Gregor69319002010-08-31 23:48:11 +00001114
1115 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1116 D->getTargetNameLoc(), TU));
1117}
1118
Douglas Gregor7e242562010-09-01 19:52:22 +00001119bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001120 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001121 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1122 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001123 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001124 }
Douglas Gregor7e242562010-09-01 19:52:22 +00001125
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001126 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1127 return true;
1128
Douglas Gregor7e242562010-09-01 19:52:22 +00001129 return VisitDeclarationNameInfo(D->getNameInfo());
1130}
1131
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001132bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001133 // Visit nested-name-specifier.
Douglas Gregordb992412011-02-25 16:33:46 +00001134 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1135 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001136 return true;
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001137
1138 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1139 D->getIdentLocation(), TU));
1140}
1141
Douglas Gregor7e242562010-09-01 19:52:22 +00001142bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001143 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001144 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1145 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001146 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001147 }
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001148
Douglas Gregor7e242562010-09-01 19:52:22 +00001149 return VisitDeclarationNameInfo(D->getNameInfo());
1150}
1151
1152bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1153 UnresolvedUsingTypenameDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001154 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001155 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1156 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001157 return true;
1158
Douglas Gregor7e242562010-09-01 19:52:22 +00001159 return false;
1160}
1161
Douglas Gregor01829d32010-08-31 14:41:23 +00001162bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1163 switch (Name.getName().getNameKind()) {
1164 case clang::DeclarationName::Identifier:
1165 case clang::DeclarationName::CXXLiteralOperatorName:
1166 case clang::DeclarationName::CXXOperatorName:
1167 case clang::DeclarationName::CXXUsingDirective:
1168 return false;
1169
1170 case clang::DeclarationName::CXXConstructorName:
1171 case clang::DeclarationName::CXXDestructorName:
1172 case clang::DeclarationName::CXXConversionFunctionName:
1173 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1174 return Visit(TSInfo->getTypeLoc());
1175 return false;
1176
1177 case clang::DeclarationName::ObjCZeroArgSelector:
1178 case clang::DeclarationName::ObjCOneArgSelector:
1179 case clang::DeclarationName::ObjCMultiArgSelector:
1180 // FIXME: Per-identifier location info?
1181 return false;
1182 }
1183
1184 return false;
1185}
1186
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001187bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1188 SourceRange Range) {
1189 // FIXME: This whole routine is a hack to work around the lack of proper
1190 // source information in nested-name-specifiers (PR5791). Since we do have
1191 // a beginning source location, we can visit the first component of the
1192 // nested-name-specifier, if it's a single-token component.
1193 if (!NNS)
1194 return false;
1195
1196 // Get the first component in the nested-name-specifier.
1197 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1198 NNS = Prefix;
1199
1200 switch (NNS->getKind()) {
1201 case NestedNameSpecifier::Namespace:
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001202 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1203 TU));
1204
Douglas Gregor14aba762011-02-24 02:36:08 +00001205 case NestedNameSpecifier::NamespaceAlias:
1206 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1207 Range.getBegin(), TU));
1208
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001209 case NestedNameSpecifier::TypeSpec: {
1210 // If the type has a form where we know that the beginning of the source
1211 // range matches up with a reference cursor. Visit the appropriate reference
1212 // cursor.
John McCallf4c73712011-01-19 06:33:43 +00001213 const Type *T = NNS->getAsType();
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001214 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1215 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1216 if (const TagType *Tag = dyn_cast<TagType>(T))
1217 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1218 if (const TemplateSpecializationType *TST
1219 = dyn_cast<TemplateSpecializationType>(T))
1220 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1221 break;
1222 }
1223
1224 case NestedNameSpecifier::TypeSpecWithTemplate:
1225 case NestedNameSpecifier::Global:
1226 case NestedNameSpecifier::Identifier:
1227 break;
1228 }
1229
1230 return false;
1231}
1232
Douglas Gregordc355712011-02-25 00:36:19 +00001233bool
1234CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1235 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1236 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1237 Qualifiers.push_back(Qualifier);
1238
1239 while (!Qualifiers.empty()) {
1240 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1241 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1242 switch (NNS->getKind()) {
1243 case NestedNameSpecifier::Namespace:
1244 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001245 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001246 TU)))
1247 return true;
1248
1249 break;
1250
1251 case NestedNameSpecifier::NamespaceAlias:
1252 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001253 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001254 TU)))
1255 return true;
1256
1257 break;
1258
1259 case NestedNameSpecifier::TypeSpec:
1260 case NestedNameSpecifier::TypeSpecWithTemplate:
1261 if (Visit(Q.getTypeLoc()))
1262 return true;
1263
1264 break;
1265
1266 case NestedNameSpecifier::Global:
1267 case NestedNameSpecifier::Identifier:
1268 break;
1269 }
1270 }
1271
1272 return false;
1273}
1274
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001275bool CursorVisitor::VisitTemplateParameters(
1276 const TemplateParameterList *Params) {
1277 if (!Params)
1278 return false;
1279
1280 for (TemplateParameterList::const_iterator P = Params->begin(),
1281 PEnd = Params->end();
1282 P != PEnd; ++P) {
1283 if (Visit(MakeCXCursor(*P, TU)))
1284 return true;
1285 }
1286
1287 return false;
1288}
1289
Douglas Gregor0b36e612010-08-31 20:37:03 +00001290bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1291 switch (Name.getKind()) {
1292 case TemplateName::Template:
1293 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1294
1295 case TemplateName::OverloadedTemplate:
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001296 // Visit the overloaded template set.
1297 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1298 return true;
1299
Douglas Gregor0b36e612010-08-31 20:37:03 +00001300 return false;
1301
1302 case TemplateName::DependentTemplate:
1303 // FIXME: Visit nested-name-specifier.
1304 return false;
1305
1306 case TemplateName::QualifiedTemplate:
1307 // FIXME: Visit nested-name-specifier.
1308 return Visit(MakeCursorTemplateRef(
1309 Name.getAsQualifiedTemplateName()->getDecl(),
1310 Loc, TU));
Douglas Gregor1aee05d2011-01-15 06:45:20 +00001311
1312 case TemplateName::SubstTemplateTemplateParmPack:
1313 return Visit(MakeCursorTemplateRef(
1314 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1315 Loc, TU));
Douglas Gregor0b36e612010-08-31 20:37:03 +00001316 }
1317
1318 return false;
1319}
1320
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001321bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1322 switch (TAL.getArgument().getKind()) {
1323 case TemplateArgument::Null:
1324 case TemplateArgument::Integral:
Douglas Gregor87dd6972010-12-20 16:52:59 +00001325 case TemplateArgument::Pack:
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001326 return false;
1327
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001328 case TemplateArgument::Type:
1329 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1330 return Visit(TSInfo->getTypeLoc());
1331 return false;
1332
1333 case TemplateArgument::Declaration:
1334 if (Expr *E = TAL.getSourceDeclExpression())
1335 return Visit(MakeCXCursor(E, StmtParent, TU));
1336 return false;
1337
1338 case TemplateArgument::Expression:
1339 if (Expr *E = TAL.getSourceExpression())
1340 return Visit(MakeCXCursor(E, StmtParent, TU));
1341 return false;
1342
1343 case TemplateArgument::Template:
Douglas Gregora7fc9012011-01-05 18:58:31 +00001344 case TemplateArgument::TemplateExpansion:
Douglas Gregorb6744ef2011-03-02 17:09:35 +00001345 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1346 return true;
1347
Douglas Gregora7fc9012011-01-05 18:58:31 +00001348 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregor0b36e612010-08-31 20:37:03 +00001349 TAL.getTemplateNameLoc());
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001350 }
1351
1352 return false;
1353}
1354
Ted Kremeneka0536d82010-05-07 01:04:29 +00001355bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1356 return VisitDeclContext(D);
1357}
1358
Douglas Gregor01829d32010-08-31 14:41:23 +00001359bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1360 return Visit(TL.getUnqualifiedLoc());
1361}
1362
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001363bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00001364 ASTContext &Context = AU->getASTContext();
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001365
1366 // Some builtin types (such as Objective-C's "id", "sel", and
1367 // "Class") have associated declarations. Create cursors for those.
1368 QualType VisitType;
1369 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001370 case BuiltinType::Void:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001371 case BuiltinType::Bool:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001372 case BuiltinType::Char_U:
1373 case BuiltinType::UChar:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001374 case BuiltinType::Char16:
1375 case BuiltinType::Char32:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001376 case BuiltinType::UShort:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001377 case BuiltinType::UInt:
1378 case BuiltinType::ULong:
1379 case BuiltinType::ULongLong:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001380 case BuiltinType::UInt128:
1381 case BuiltinType::Char_S:
1382 case BuiltinType::SChar:
Chris Lattner3f59c972010-12-25 23:25:43 +00001383 case BuiltinType::WChar_U:
1384 case BuiltinType::WChar_S:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001385 case BuiltinType::Short:
1386 case BuiltinType::Int:
1387 case BuiltinType::Long:
1388 case BuiltinType::LongLong:
1389 case BuiltinType::Int128:
1390 case BuiltinType::Float:
1391 case BuiltinType::Double:
1392 case BuiltinType::LongDouble:
1393 case BuiltinType::NullPtr:
1394 case BuiltinType::Overload:
1395 case BuiltinType::Dependent:
John McCall1de4d4e2011-04-07 08:22:57 +00001396 case BuiltinType::UnknownAny:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001397 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001398
Ted Kremenekc4174cc2010-02-18 18:52:18 +00001399 case BuiltinType::ObjCId:
1400 VisitType = Context.getObjCIdType();
1401 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001402
1403 case BuiltinType::ObjCClass:
1404 VisitType = Context.getObjCClassType();
1405 break;
1406
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001407 case BuiltinType::ObjCSel:
1408 VisitType = Context.getObjCSelType();
1409 break;
1410 }
1411
1412 if (!VisitType.isNull()) {
1413 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001414 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001415 TU));
1416 }
1417
1418 return false;
1419}
1420
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001421bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1422 return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
1423}
1424
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001425bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1426 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1427}
1428
1429bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1430 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1431}
1432
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001433bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001434 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001435 // no context information with which we can match up the depth/index in the
1436 // type to the appropriate
1437 return false;
1438}
1439
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001440bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1441 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1442 return true;
1443
John McCallc12c5bb2010-05-15 11:32:37 +00001444 return false;
1445}
1446
1447bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1448 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1449 return true;
1450
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001451 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1452 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1453 TU)))
1454 return true;
1455 }
1456
1457 return false;
1458}
1459
1460bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCallc12c5bb2010-05-15 11:32:37 +00001461 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001462}
1463
Abramo Bagnara075f8f12010-12-10 16:29:40 +00001464bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1465 return Visit(TL.getInnerLoc());
1466}
1467
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001468bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1469 return Visit(TL.getPointeeLoc());
1470}
1471
1472bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1473 return Visit(TL.getPointeeLoc());
1474}
1475
1476bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1477 return Visit(TL.getPointeeLoc());
1478}
1479
1480bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001481 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001482}
1483
1484bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001485 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001486}
1487
Douglas Gregor01829d32010-08-31 14:41:23 +00001488bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1489 bool SkipResultType) {
1490 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001491 return true;
1492
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001493 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek5dbacb42010-04-07 00:27:13 +00001494 if (Decl *D = TL.getArg(I))
1495 if (Visit(MakeCXCursor(D, TU)))
1496 return true;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001497
1498 return false;
1499}
1500
1501bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1502 if (Visit(TL.getElementLoc()))
1503 return true;
1504
1505 if (Expr *Size = TL.getSizeExpr())
1506 return Visit(MakeCXCursor(Size, StmtParent, TU));
1507
1508 return false;
1509}
1510
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001511bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1512 TemplateSpecializationTypeLoc TL) {
Douglas Gregor0b36e612010-08-31 20:37:03 +00001513 // Visit the template name.
1514 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1515 TL.getTemplateNameLoc()))
1516 return true;
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001517
1518 // Visit the template arguments.
1519 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1520 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1521 return true;
1522
1523 return false;
1524}
1525
Douglas Gregor2332c112010-01-21 20:48:56 +00001526bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1527 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1528}
1529
1530bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1531 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1532 return Visit(TSInfo->getTypeLoc());
1533
1534 return false;
1535}
1536
Douglas Gregor2494dd02011-03-01 01:34:45 +00001537bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1538 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1539 return true;
1540
1541 return false;
1542}
1543
Douglas Gregor94fdffa2011-03-01 20:11:18 +00001544bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1545 DependentTemplateSpecializationTypeLoc TL) {
1546 // Visit the nested-name-specifier, if there is one.
1547 if (TL.getQualifierLoc() &&
1548 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1549 return true;
1550
1551 // Visit the template arguments.
1552 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1553 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1554 return true;
1555
1556 return false;
1557}
1558
Douglas Gregor9e876872011-03-01 18:12:44 +00001559bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1560 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1561 return true;
1562
1563 return Visit(TL.getNamedTypeLoc());
1564}
1565
Douglas Gregor7536dd52010-12-20 02:24:11 +00001566bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1567 return Visit(TL.getPatternLoc());
1568}
1569
Ted Kremenek3064ef92010-08-27 21:34:58 +00001570bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001571 // Visit the nested-name-specifier, if present.
1572 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1573 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1574 return true;
1575
Ted Kremenek3064ef92010-08-27 21:34:58 +00001576 if (D->isDefinition()) {
1577 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1578 E = D->bases_end(); I != E; ++I) {
1579 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1580 return true;
1581 }
1582 }
1583
1584 return VisitTagDecl(D);
1585}
1586
Ted Kremenek09dfa372010-02-18 05:46:33 +00001587bool CursorVisitor::VisitAttributes(Decl *D) {
Sean Huntcf807c42010-08-18 23:23:40 +00001588 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1589 i != e; ++i)
1590 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek09dfa372010-02-18 05:46:33 +00001591 return true;
1592
1593 return false;
1594}
1595
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001596//===----------------------------------------------------------------------===//
1597// Data-recursive visitor methods.
1598//===----------------------------------------------------------------------===//
1599
Ted Kremenek28a71942010-11-13 00:36:47 +00001600namespace {
Ted Kremenek035dc412010-11-13 00:36:50 +00001601#define DEF_JOB(NAME, DATA, KIND)\
1602class NAME : public VisitorJob {\
1603public:\
1604 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1605 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenekf64d8032010-11-18 00:02:32 +00001606 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek035dc412010-11-13 00:36:50 +00001607};
1608
1609DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1610DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001611DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001612DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek60608ec2010-11-17 00:50:47 +00001613DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1614 ExplicitTemplateArgsVisitKind)
Douglas Gregor94d96292011-01-19 20:34:17 +00001615DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001616#undef DEF_JOB
1617
1618class DeclVisit : public VisitorJob {
1619public:
1620 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1621 VisitorJob(parent, VisitorJob::DeclVisitKind,
1622 d, isFirst ? (void*) 1 : (void*) 0) {}
1623 static bool classof(const VisitorJob *VJ) {
Ted Kremenek82f3c502010-11-15 22:23:26 +00001624 return VJ->getKind() == DeclVisitKind;
Ted Kremenek035dc412010-11-13 00:36:50 +00001625 }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001626 Decl *get() const { return static_cast<Decl*>(data[0]); }
1627 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek035dc412010-11-13 00:36:50 +00001628};
Ted Kremenek035dc412010-11-13 00:36:50 +00001629class TypeLocVisit : public VisitorJob {
1630public:
1631 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1632 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1633 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1634
1635 static bool classof(const VisitorJob *VJ) {
1636 return VJ->getKind() == TypeLocVisitKind;
1637 }
1638
Ted Kremenek82f3c502010-11-15 22:23:26 +00001639 TypeLoc get() const {
Ted Kremenekf64d8032010-11-18 00:02:32 +00001640 QualType T = QualType::getFromOpaquePtr(data[0]);
1641 return TypeLoc(T, data[1]);
Ted Kremenek035dc412010-11-13 00:36:50 +00001642 }
1643};
1644
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001645class LabelRefVisit : public VisitorJob {
1646public:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001647 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1648 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001649 labelLoc.getPtrEncoding()) {}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001650
1651 static bool classof(const VisitorJob *VJ) {
1652 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1653 }
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001654 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001655 SourceLocation getLoc() const {
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001656 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001657};
1658class NestedNameSpecifierVisit : public VisitorJob {
1659public:
1660 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1661 CXCursor parent)
1662 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001663 NS, R.getBegin().getPtrEncoding(),
1664 R.getEnd().getPtrEncoding()) {}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001665 static bool classof(const VisitorJob *VJ) {
1666 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1667 }
1668 NestedNameSpecifier *get() const {
1669 return static_cast<NestedNameSpecifier*>(data[0]);
1670 }
1671 SourceRange getSourceRange() const {
1672 SourceLocation A =
1673 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1674 SourceLocation B =
1675 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1676 return SourceRange(A, B);
1677 }
1678};
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001679
1680class NestedNameSpecifierLocVisit : public VisitorJob {
1681public:
1682 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1683 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1684 Qualifier.getNestedNameSpecifier(),
1685 Qualifier.getOpaqueData()) { }
1686
1687 static bool classof(const VisitorJob *VJ) {
1688 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1689 }
1690
1691 NestedNameSpecifierLoc get() const {
1692 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1693 data[1]);
1694 }
1695};
1696
Ted Kremenekf64d8032010-11-18 00:02:32 +00001697class DeclarationNameInfoVisit : public VisitorJob {
1698public:
1699 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1700 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1701 static bool classof(const VisitorJob *VJ) {
1702 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1703 }
1704 DeclarationNameInfo get() const {
1705 Stmt *S = static_cast<Stmt*>(data[0]);
1706 switch (S->getStmtClass()) {
1707 default:
1708 llvm_unreachable("Unhandled Stmt");
1709 case Stmt::CXXDependentScopeMemberExprClass:
1710 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1711 case Stmt::DependentScopeDeclRefExprClass:
1712 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1713 }
1714 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001715};
Ted Kremenekcdba6592010-11-18 00:42:18 +00001716class MemberRefVisit : public VisitorJob {
1717public:
1718 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1719 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001720 L.getPtrEncoding()) {}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001721 static bool classof(const VisitorJob *VJ) {
1722 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1723 }
1724 FieldDecl *get() const {
1725 return static_cast<FieldDecl*>(data[0]);
1726 }
1727 SourceLocation getLoc() const {
1728 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1729 }
1730};
Ted Kremenek28a71942010-11-13 00:36:47 +00001731class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1732 VisitorWorkList &WL;
1733 CXCursor Parent;
1734public:
1735 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1736 : WL(wl), Parent(parent) {}
1737
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001738 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001739 void VisitBlockExpr(BlockExpr *B);
Ted Kremenek28a71942010-11-13 00:36:47 +00001740 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenek083c7e22010-11-13 05:38:03 +00001741 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001742 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001743 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001744 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001745 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001746 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001747 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001748 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001749 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek55b933a2010-11-17 00:50:36 +00001750 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001751 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001752 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek035dc412010-11-13 00:36:50 +00001753 void VisitDeclStmt(DeclStmt *S);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001754 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001755 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001756 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1757 void VisitForStmt(ForStmt *FS);
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001758 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenek28a71942010-11-13 00:36:47 +00001759 void VisitIfStmt(IfStmt *If);
1760 void VisitInitListExpr(InitListExpr *IE);
1761 void VisitMemberExpr(MemberExpr *M);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001762 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001763 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001764 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1765 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00001766 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001767 void VisitStmt(Stmt *S);
1768 void VisitSwitchStmt(SwitchStmt *S);
1769 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek2939b6f2010-11-17 00:50:50 +00001770 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet6ad6f282010-12-07 00:08:36 +00001771 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001772 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenek9d3bf792010-11-17 00:50:43 +00001773 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor94d96292011-01-19 20:34:17 +00001774 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregoree8aff02011-01-04 17:33:58 +00001775
Ted Kremenek28a71942010-11-13 00:36:47 +00001776private:
Ted Kremenekf64d8032010-11-18 00:02:32 +00001777 void AddDeclarationNameInfo(Stmt *S);
1778 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001779 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek60608ec2010-11-17 00:50:47 +00001780 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001781 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenek28a71942010-11-13 00:36:47 +00001782 void AddStmt(Stmt *S);
Ted Kremenek035dc412010-11-13 00:36:50 +00001783 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenek28a71942010-11-13 00:36:47 +00001784 void AddTypeLoc(TypeSourceInfo *TI);
1785 void EnqueueChildren(Stmt *S);
1786};
1787} // end anonyous namespace
1788
Ted Kremenekf64d8032010-11-18 00:02:32 +00001789void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1790 // 'S' should always be non-null, since it comes from the
1791 // statement we are visiting.
1792 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1793}
1794void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1795 SourceRange R) {
1796 if (N)
1797 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1798}
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001799
1800void
1801EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1802 if (Qualifier)
1803 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1804}
1805
Ted Kremenek28a71942010-11-13 00:36:47 +00001806void EnqueueVisitor::AddStmt(Stmt *S) {
1807 if (S)
1808 WL.push_back(StmtVisit(S, Parent));
1809}
Ted Kremenek035dc412010-11-13 00:36:50 +00001810void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001811 if (D)
Ted Kremenek035dc412010-11-13 00:36:50 +00001812 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenek28a71942010-11-13 00:36:47 +00001813}
Ted Kremenek60608ec2010-11-17 00:50:47 +00001814void EnqueueVisitor::
1815 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1816 if (A)
1817 WL.push_back(ExplicitTemplateArgsVisit(
1818 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1819}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001820void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1821 if (D)
1822 WL.push_back(MemberRefVisit(D, L, Parent));
1823}
Ted Kremenek28a71942010-11-13 00:36:47 +00001824void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1825 if (TI)
1826 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1827 }
1828void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremeneka6b70432010-11-12 21:34:09 +00001829 unsigned size = WL.size();
John McCall7502c1d2011-02-13 04:07:26 +00001830 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001831 AddStmt(*Child);
Ted Kremeneka6b70432010-11-12 21:34:09 +00001832 }
1833 if (size == WL.size())
1834 return;
1835 // Now reverse the entries we just added. This will match the DFS
1836 // ordering performed by the worklist.
1837 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1838 std::reverse(I, E);
1839}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001840void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1841 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1842}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001843void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1844 AddDecl(B->getBlockDecl());
1845}
Ted Kremenek28a71942010-11-13 00:36:47 +00001846void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1847 EnqueueChildren(E);
1848 AddTypeLoc(E->getTypeSourceInfo());
1849}
Ted Kremenek083c7e22010-11-13 05:38:03 +00001850void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1851 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1852 E = S->body_rend(); I != E; ++I) {
1853 AddStmt(*I);
1854 }
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001855}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001856void EnqueueVisitor::
1857VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1858 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1859 AddDeclarationNameInfo(E);
Douglas Gregor7c3179c2011-02-28 18:50:33 +00001860 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1861 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001862 if (!E->isImplicitAccess())
1863 AddStmt(E->getBase());
1864}
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001865void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1866 // Enqueue the initializer or constructor arguments.
1867 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1868 AddStmt(E->getConstructorArg(I-1));
1869 // Enqueue the array size, if any.
1870 AddStmt(E->getArraySize());
1871 // Enqueue the allocated type.
1872 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1873 // Enqueue the placement arguments.
1874 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1875 AddStmt(E->getPlacementArg(I-1));
1876}
Ted Kremenek28a71942010-11-13 00:36:47 +00001877void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenek8b8d8c92010-11-13 05:55:56 +00001878 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1879 AddStmt(CE->getArg(I-1));
Ted Kremenek28a71942010-11-13 00:36:47 +00001880 AddStmt(CE->getCallee());
1881 AddStmt(CE->getArg(0));
1882}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001883void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1884 // Visit the name of the type being destroyed.
1885 AddTypeLoc(E->getDestroyedTypeInfo());
1886 // Visit the scope type that looks disturbingly like the nested-name-specifier
1887 // but isn't.
1888 AddTypeLoc(E->getScopeTypeInfo());
1889 // Visit the nested-name-specifier.
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001890 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1891 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001892 // Visit base expression.
1893 AddStmt(E->getBase());
1894}
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001895void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1896 AddTypeLoc(E->getTypeSourceInfo());
1897}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001898void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1899 EnqueueChildren(E);
1900 AddTypeLoc(E->getTypeSourceInfo());
1901}
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001902void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1903 EnqueueChildren(E);
1904 if (E->isTypeOperand())
1905 AddTypeLoc(E->getTypeOperandSourceInfo());
1906}
Ted Kremenek55b933a2010-11-17 00:50:36 +00001907
1908void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1909 *E) {
1910 EnqueueChildren(E);
1911 AddTypeLoc(E->getTypeSourceInfo());
1912}
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001913void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1914 EnqueueChildren(E);
1915 if (E->isTypeOperand())
1916 AddTypeLoc(E->getTypeOperandSourceInfo());
1917}
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001918void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00001919 if (DR->hasExplicitTemplateArgs()) {
1920 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1921 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001922 WL.push_back(DeclRefExprParts(DR, Parent));
1923}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001924void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1925 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1926 AddDeclarationNameInfo(E);
Douglas Gregor00cf3cc2011-02-25 20:49:16 +00001927 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenekf64d8032010-11-18 00:02:32 +00001928}
Ted Kremenek035dc412010-11-13 00:36:50 +00001929void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1930 unsigned size = WL.size();
1931 bool isFirst = true;
1932 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1933 D != DEnd; ++D) {
1934 AddDecl(*D, isFirst);
1935 isFirst = false;
1936 }
1937 if (size == WL.size())
1938 return;
1939 // Now reverse the entries we just added. This will match the DFS
1940 // ordering performed by the worklist.
1941 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1942 std::reverse(I, E);
1943}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001944void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1945 AddStmt(E->getInit());
1946 typedef DesignatedInitExpr::Designator Designator;
1947 for (DesignatedInitExpr::reverse_designators_iterator
1948 D = E->designators_rbegin(), DEnd = E->designators_rend();
1949 D != DEnd; ++D) {
1950 if (D->isFieldDesignator()) {
1951 if (FieldDecl *Field = D->getField())
1952 AddMemberRef(Field, D->getFieldLoc());
1953 continue;
1954 }
1955 if (D->isArrayDesignator()) {
1956 AddStmt(E->getArrayIndex(*D));
1957 continue;
1958 }
1959 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1960 AddStmt(E->getArrayRangeEnd(*D));
1961 AddStmt(E->getArrayRangeStart(*D));
1962 }
1963}
Ted Kremenek28a71942010-11-13 00:36:47 +00001964void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1965 EnqueueChildren(E);
1966 AddTypeLoc(E->getTypeInfoAsWritten());
1967}
1968void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1969 AddStmt(FS->getBody());
1970 AddStmt(FS->getInc());
1971 AddStmt(FS->getCond());
1972 AddDecl(FS->getConditionVariable());
1973 AddStmt(FS->getInit());
1974}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001975void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1976 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1977}
Ted Kremenek28a71942010-11-13 00:36:47 +00001978void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
1979 AddStmt(If->getElse());
1980 AddStmt(If->getThen());
1981 AddStmt(If->getCond());
1982 AddDecl(If->getConditionVariable());
1983}
1984void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
1985 // We care about the syntactic form of the initializer list, only.
1986 if (InitListExpr *Syntactic = IE->getSyntacticForm())
1987 IE = Syntactic;
1988 EnqueueChildren(IE);
1989}
1990void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor89629a72010-11-17 17:15:08 +00001991 WL.push_back(MemberExprParts(M, Parent));
1992
1993 // If the base of the member access expression is an implicit 'this', don't
1994 // visit it.
1995 // FIXME: If we ever want to show these implicit accesses, this will be
1996 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor75e85042011-03-02 21:06:53 +00001997 if (!M->isImplicitAccess())
1998 AddStmt(M->getBase());
Ted Kremenek28a71942010-11-13 00:36:47 +00001999}
Ted Kremenek73d15c42010-11-13 01:09:29 +00002000void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2001 AddTypeLoc(E->getEncodedTypeSourceInfo());
2002}
Ted Kremenek28a71942010-11-13 00:36:47 +00002003void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2004 EnqueueChildren(M);
2005 AddTypeLoc(M->getClassReceiverTypeInfo());
2006}
Ted Kremenekcdba6592010-11-18 00:42:18 +00002007void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2008 // Visit the components of the offsetof expression.
2009 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2010 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2011 const OffsetOfNode &Node = E->getComponent(I-1);
2012 switch (Node.getKind()) {
2013 case OffsetOfNode::Array:
2014 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2015 break;
2016 case OffsetOfNode::Field:
Abramo Bagnara06dec892011-03-12 09:45:03 +00002017 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenekcdba6592010-11-18 00:42:18 +00002018 break;
2019 case OffsetOfNode::Identifier:
2020 case OffsetOfNode::Base:
2021 continue;
2022 }
2023 }
2024 // Visit the type into which we're computing the offset.
2025 AddTypeLoc(E->getTypeSourceInfo());
2026}
Ted Kremenek28a71942010-11-13 00:36:47 +00002027void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00002028 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenek60458782010-11-12 21:34:16 +00002029 WL.push_back(OverloadExprParts(E, Parent));
2030}
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00002031void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2032 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00002033 EnqueueChildren(E);
2034 if (E->isArgumentType())
2035 AddTypeLoc(E->getArgumentTypeInfo());
2036}
Ted Kremenek28a71942010-11-13 00:36:47 +00002037void EnqueueVisitor::VisitStmt(Stmt *S) {
2038 EnqueueChildren(S);
2039}
2040void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2041 AddStmt(S->getBody());
2042 AddStmt(S->getCond());
2043 AddDecl(S->getConditionVariable());
2044}
Ted Kremenekfafa75a2010-11-17 00:50:39 +00002045
Ted Kremenek28a71942010-11-13 00:36:47 +00002046void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2047 AddStmt(W->getBody());
2048 AddStmt(W->getCond());
2049 AddDecl(W->getConditionVariable());
2050}
Ted Kremenek2939b6f2010-11-17 00:50:50 +00002051void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2052 AddTypeLoc(E->getQueriedTypeSourceInfo());
2053}
Francois Pichet6ad6f282010-12-07 00:08:36 +00002054
2055void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet6ad6f282010-12-07 00:08:36 +00002056 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichet0a03a3f2010-12-08 09:11:05 +00002057 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet6ad6f282010-12-07 00:08:36 +00002058}
2059
Ted Kremenek28a71942010-11-13 00:36:47 +00002060void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2061 VisitOverloadExpr(U);
2062 if (!U->isImplicitAccess())
2063 AddStmt(U->getBase());
2064}
Ted Kremenek9d3bf792010-11-17 00:50:43 +00002065void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2066 AddStmt(E->getSubExpr());
2067 AddTypeLoc(E->getWrittenTypeInfo());
2068}
Douglas Gregor94d96292011-01-19 20:34:17 +00002069void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2070 WL.push_back(SizeOfPackExprParts(E, Parent));
2071}
Ted Kremenek60458782010-11-12 21:34:16 +00002072
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002073void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenek28a71942010-11-13 00:36:47 +00002074 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002075}
2076
2077bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2078 if (RegionOfInterest.isValid()) {
2079 SourceRange Range = getRawCursorExtent(C);
2080 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2081 return false;
2082 }
2083 return true;
2084}
2085
2086bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2087 while (!WL.empty()) {
2088 // Dequeue the worklist item.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002089 VisitorJob LI = WL.back();
2090 WL.pop_back();
2091
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002092 // Set the Parent field, then back to its old value once we're done.
2093 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2094
2095 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00002096 case VisitorJob::DeclVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002097 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenekf1107452010-11-12 18:26:56 +00002098 if (!D)
2099 continue;
2100
2101 // For now, perform default visitation for Decls.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002102 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenekf1107452010-11-12 18:26:56 +00002103 return true;
2104
2105 continue;
2106 }
Ted Kremenek60608ec2010-11-17 00:50:47 +00002107 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2108 const ExplicitTemplateArgumentList *ArgList =
2109 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2110 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2111 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2112 Arg != ArgEnd; ++Arg) {
2113 if (VisitTemplateArgumentLoc(*Arg))
2114 return true;
2115 }
2116 continue;
2117 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002118 case VisitorJob::TypeLocVisitKind: {
2119 // Perform default visitation for TypeLocs.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002120 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002121 return true;
2122 continue;
2123 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002124 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002125 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremeneke7455012011-02-23 04:54:51 +00002126 if (LabelStmt *stmt = LS->getStmt()) {
2127 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2128 TU))) {
2129 return true;
2130 }
2131 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002132 continue;
2133 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002134
Ted Kremenekf64d8032010-11-18 00:02:32 +00002135 case VisitorJob::NestedNameSpecifierVisitKind: {
2136 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2137 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2138 return true;
2139 continue;
2140 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002141
2142 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2143 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2144 if (VisitNestedNameSpecifierLoc(V->get()))
2145 return true;
2146 continue;
2147 }
2148
Ted Kremenekf64d8032010-11-18 00:02:32 +00002149 case VisitorJob::DeclarationNameInfoVisitKind: {
2150 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2151 ->get()))
2152 return true;
2153 continue;
2154 }
Ted Kremenekcdba6592010-11-18 00:42:18 +00002155 case VisitorJob::MemberRefVisitKind: {
2156 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2157 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2158 return true;
2159 continue;
2160 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002161 case VisitorJob::StmtVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002162 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002163 if (!S)
2164 continue;
2165
Ted Kremenekf1107452010-11-12 18:26:56 +00002166 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002167 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenekcdba6592010-11-18 00:42:18 +00002168 if (!IsInRegionOfInterest(Cursor))
2169 continue;
2170 switch (Visitor(Cursor, Parent, ClientData)) {
2171 case CXChildVisit_Break: return true;
2172 case CXChildVisit_Continue: break;
2173 case CXChildVisit_Recurse:
2174 EnqueueWorkList(WL, S);
Ted Kremenek82f3c502010-11-15 22:23:26 +00002175 break;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002176 }
Ted Kremenek82f3c502010-11-15 22:23:26 +00002177 continue;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002178 }
2179 case VisitorJob::MemberExprPartsKind: {
2180 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002181 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002182
2183 // Visit the nested-name-specifier
Douglas Gregor40d96a62011-02-28 21:54:11 +00002184 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2185 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002186 return true;
2187
2188 // Visit the declaration name.
2189 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2190 return true;
2191
2192 // Visit the explicitly-specified template arguments, if any.
2193 if (M->hasExplicitTemplateArgs()) {
2194 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2195 *ArgEnd = Arg + M->getNumTemplateArgs();
2196 Arg != ArgEnd; ++Arg) {
2197 if (VisitTemplateArgumentLoc(*Arg))
2198 return true;
2199 }
2200 }
2201 continue;
2202 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002203 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002204 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002205 // Visit nested-name-specifier, if present.
Douglas Gregor40d96a62011-02-28 21:54:11 +00002206 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2207 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002208 return true;
2209 // Visit declaration name.
2210 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2211 return true;
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002212 continue;
2213 }
Ted Kremenek60458782010-11-12 21:34:16 +00002214 case VisitorJob::OverloadExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002215 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenek60458782010-11-12 21:34:16 +00002216 // Visit the nested-name-specifier.
Douglas Gregor4c9be892011-02-28 20:01:57 +00002217 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2218 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek60458782010-11-12 21:34:16 +00002219 return true;
2220 // Visit the declaration name.
2221 if (VisitDeclarationNameInfo(O->getNameInfo()))
2222 return true;
2223 // Visit the overloaded declaration reference.
2224 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2225 return true;
Ted Kremenek60458782010-11-12 21:34:16 +00002226 continue;
2227 }
Douglas Gregor94d96292011-01-19 20:34:17 +00002228 case VisitorJob::SizeOfPackExprPartsKind: {
2229 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2230 NamedDecl *Pack = E->getPack();
2231 if (isa<TemplateTypeParmDecl>(Pack)) {
2232 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2233 E->getPackLoc(), TU)))
2234 return true;
2235
2236 continue;
2237 }
2238
2239 if (isa<TemplateTemplateParmDecl>(Pack)) {
2240 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2241 E->getPackLoc(), TU)))
2242 return true;
2243
2244 continue;
2245 }
2246
2247 // Non-type template parameter packs and function parameter packs are
2248 // treated like DeclRefExpr cursors.
2249 continue;
2250 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002251 }
2252 }
2253 return false;
2254}
2255
Ted Kremenekcdba6592010-11-18 00:42:18 +00002256bool CursorVisitor::Visit(Stmt *S) {
Ted Kremenekd1ded662010-11-15 23:31:32 +00002257 VisitorWorkList *WL = 0;
2258 if (!WorkListFreeList.empty()) {
2259 WL = WorkListFreeList.back();
2260 WL->clear();
2261 WorkListFreeList.pop_back();
2262 }
2263 else {
2264 WL = new VisitorWorkList();
2265 WorkListCache.push_back(WL);
2266 }
2267 EnqueueWorkList(*WL, S);
2268 bool result = RunVisitorWorkList(*WL);
2269 WorkListFreeList.push_back(WL);
2270 return result;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002271}
2272
2273//===----------------------------------------------------------------------===//
2274// Misc. API hooks.
2275//===----------------------------------------------------------------------===//
2276
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002277static llvm::sys::Mutex EnableMultithreadingMutex;
2278static bool EnabledMultithreading;
2279
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002280extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002281CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2282 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002283 // Disable pretty stack trace functionality, which will otherwise be a very
2284 // poor citizen of the world and set up all sorts of signal handlers.
2285 llvm::DisablePrettyStackTrace = true;
2286
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002287 // We use crash recovery to make some of our APIs more reliable, implicitly
2288 // enable it.
2289 llvm::CrashRecoveryContext::Enable();
2290
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002291 // Enable support for multithreading in LLVM.
2292 {
2293 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2294 if (!EnabledMultithreading) {
2295 llvm::llvm_start_multithreaded();
2296 EnabledMultithreading = true;
2297 }
2298 }
2299
Douglas Gregora030b7c2010-01-22 20:35:53 +00002300 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002301 if (excludeDeclarationsFromPCH)
2302 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002303 if (displayDiagnostics)
2304 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002305 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002306}
2307
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002308void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002309 if (CIdx)
2310 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002311}
2312
Ted Kremenekd2427dd2011-03-18 23:05:39 +00002313void clang_toggleCrashRecovery(unsigned isEnabled) {
2314 if (isEnabled)
2315 llvm::CrashRecoveryContext::Enable();
2316 else
2317 llvm::CrashRecoveryContext::Disable();
2318}
2319
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002320CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002321 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002322 if (!CIdx)
2323 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002324
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002325 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002326 FileSystemOptions FileSystemOpts;
2327 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002328
Douglas Gregor28019772010-04-05 23:52:57 +00002329 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremeneka60ed472010-11-16 08:15:36 +00002330 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002331 CXXIdx->getOnlyLocalDecls(),
2332 0, 0, true);
Ted Kremeneka60ed472010-11-16 08:15:36 +00002333 return MakeCXTranslationUnit(TU);
Steve Naroff600866c2009-08-27 19:51:58 +00002334}
2335
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002336unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002337 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002338 CXTranslationUnit_CacheCompletionResults |
2339 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002340}
2341
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002342CXTranslationUnit
2343clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2344 const char *source_filename,
2345 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002346 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002347 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002348 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor5a430212010-07-21 18:52:53 +00002349 return clang_parseTranslationUnit(CIdx, source_filename,
2350 command_line_args, num_command_line_args,
2351 unsaved_files, num_unsaved_files,
2352 CXTranslationUnit_DetailedPreprocessingRecord);
2353}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002354
2355struct ParseTranslationUnitInfo {
2356 CXIndex CIdx;
2357 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002358 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002359 int num_command_line_args;
2360 struct CXUnsavedFile *unsaved_files;
2361 unsigned num_unsaved_files;
2362 unsigned options;
2363 CXTranslationUnit result;
2364};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002365static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002366 ParseTranslationUnitInfo *PTUI =
2367 static_cast<ParseTranslationUnitInfo*>(UserData);
2368 CXIndex CIdx = PTUI->CIdx;
2369 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002370 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002371 int num_command_line_args = PTUI->num_command_line_args;
2372 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2373 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2374 unsigned options = PTUI->options;
2375 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002376
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002377 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002378 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002379
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002380 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2381
Douglas Gregor44c181a2010-07-23 00:33:23 +00002382 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002383 bool CompleteTranslationUnit
2384 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002385 bool CacheCodeCompetionResults
2386 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002387 bool CXXPrecompilePreamble
2388 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2389 bool CXXChainedPCH
2390 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002391
Douglas Gregor5352ac02010-01-28 00:27:43 +00002392 // Configure the diagnostics.
2393 DiagnosticOptions DiagOpts;
Ted Kremenek25a11e12011-03-22 01:15:24 +00002394 llvm::IntrusiveRefCntPtr<Diagnostic>
2395 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2396 command_line_args));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002397
Ted Kremenek25a11e12011-03-22 01:15:24 +00002398 // Recover resources if we crash before exiting this function.
2399 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2400 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2401 DiagCleanup(Diags.getPtr());
2402
2403 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2404 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2405
2406 // Recover resources if we crash before exiting this function.
2407 llvm::CrashRecoveryContextCleanupRegistrar<
2408 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2409
Douglas Gregor4db64a42010-01-23 00:14:00 +00002410 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002411 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002412 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002413 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002414 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2415 Buffer));
Douglas Gregor4db64a42010-01-23 00:14:00 +00002416 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002417
Ted Kremenek25a11e12011-03-22 01:15:24 +00002418 llvm::OwningPtr<std::vector<const char *> >
2419 Args(new std::vector<const char*>());
2420
2421 // Recover resources if we crash before exiting this method.
2422 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2423 ArgsCleanup(Args.get());
2424
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002425 // Since the Clang C library is primarily used by batch tools dealing with
2426 // (often very broken) source code, where spell-checking can have a
2427 // significant negative impact on performance (particularly when
2428 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002429 // Only do this if we haven't found a spell-checking-related argument.
2430 bool FoundSpellCheckingArgument = false;
2431 for (int I = 0; I != num_command_line_args; ++I) {
2432 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2433 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2434 FoundSpellCheckingArgument = true;
2435 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002436 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002437 }
2438 if (!FoundSpellCheckingArgument)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002439 Args->push_back("-fno-spell-checking");
Douglas Gregorb10daed2010-10-11 16:52:23 +00002440
Ted Kremenek25a11e12011-03-22 01:15:24 +00002441 Args->insert(Args->end(), command_line_args,
2442 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002443
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002444 // The 'source_filename' argument is optional. If the caller does not
2445 // specify it then it is assumed that the source file is specified
2446 // in the actual argument list.
2447 // Put the source file after command_line_args otherwise if '-x' flag is
2448 // present it will be unused.
2449 if (source_filename)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002450 Args->push_back(source_filename);
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002451
Douglas Gregor44c181a2010-07-23 00:33:23 +00002452 // Do we need the detailed preprocessing record?
2453 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek25a11e12011-03-22 01:15:24 +00002454 Args->push_back("-Xclang");
2455 Args->push_back("-detailed-preprocessing-record");
Douglas Gregor44c181a2010-07-23 00:33:23 +00002456 }
2457
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002458 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002459 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek4ee99262011-03-22 20:16:19 +00002460 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2461 /* vector::data() not portable */,
2462 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002463 Diags,
2464 CXXIdx->getClangResourcesPath(),
2465 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002466 /*CaptureDiagnostics=*/true,
Ted Kremenek4ee99262011-03-22 20:16:19 +00002467 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek25a11e12011-03-22 01:15:24 +00002468 RemappedFiles->size(),
Argyrios Kyrtzidis299a4a92011-03-08 23:35:24 +00002469 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002470 PrecompilePreamble,
2471 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002472 CacheCodeCompetionResults,
2473 CXXPrecompilePreamble,
2474 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002475
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002476 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002477 // Make sure to check that 'Unit' is non-NULL.
2478 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2479 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2480 DEnd = Unit->stored_diag_end();
2481 D != DEnd; ++D) {
2482 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2483 CXString Msg = clang_formatDiagnostic(&Diag,
2484 clang_defaultDiagnosticDisplayOptions());
2485 fprintf(stderr, "%s\n", clang_getCString(Msg));
2486 clang_disposeString(Msg);
2487 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002488#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002489 // On Windows, force a flush, since there may be multiple copies of
2490 // stderr and stdout in the file system, all with different buffers
2491 // but writing to the same device.
2492 fflush(stderr);
2493#endif
2494 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002495 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002496
Ted Kremeneka60ed472010-11-16 08:15:36 +00002497 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002498}
2499CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2500 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002501 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002502 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002503 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002504 unsigned num_unsaved_files,
2505 unsigned options) {
2506 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002507 num_command_line_args, unsaved_files,
2508 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002509 llvm::CrashRecoveryContext CRC;
2510
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002511 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002512 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2513 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2514 fprintf(stderr, " 'command_line_args' : [");
2515 for (int i = 0; i != num_command_line_args; ++i) {
2516 if (i)
2517 fprintf(stderr, ", ");
2518 fprintf(stderr, "'%s'", command_line_args[i]);
2519 }
2520 fprintf(stderr, "],\n");
2521 fprintf(stderr, " 'unsaved_files' : [");
2522 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2523 if (i)
2524 fprintf(stderr, ", ");
2525 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2526 unsaved_files[i].Length);
2527 }
2528 fprintf(stderr, "],\n");
2529 fprintf(stderr, " 'options' : %d,\n", options);
2530 fprintf(stderr, "}\n");
2531
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002532 return 0;
2533 }
2534
2535 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002536}
2537
Douglas Gregor19998442010-08-13 15:35:05 +00002538unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2539 return CXSaveTranslationUnit_None;
2540}
2541
2542int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2543 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002544 if (!TU)
2545 return 1;
2546
Ted Kremeneka60ed472010-11-16 08:15:36 +00002547 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002548}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002549
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002550void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002551 if (CTUnit) {
2552 // If the translation unit has been marked as unsafe to free, just discard
2553 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002554 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002555 return;
2556
Ted Kremeneka60ed472010-11-16 08:15:36 +00002557 delete static_cast<ASTUnit *>(CTUnit->TUData);
2558 disposeCXStringPool(CTUnit->StringPool);
2559 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002560 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002561}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002562
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002563unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2564 return CXReparse_None;
2565}
2566
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002567struct ReparseTranslationUnitInfo {
2568 CXTranslationUnit TU;
2569 unsigned num_unsaved_files;
2570 struct CXUnsavedFile *unsaved_files;
2571 unsigned options;
2572 int result;
2573};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002574
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002575static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002576 ReparseTranslationUnitInfo *RTUI =
2577 static_cast<ReparseTranslationUnitInfo*>(UserData);
2578 CXTranslationUnit TU = RTUI->TU;
2579 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2580 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2581 unsigned options = RTUI->options;
2582 (void) options;
2583 RTUI->result = 1;
2584
Douglas Gregorabc563f2010-07-19 21:46:24 +00002585 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002586 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002587
Ted Kremeneka60ed472010-11-16 08:15:36 +00002588 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002589 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002590
Ted Kremenek25a11e12011-03-22 01:15:24 +00002591 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2592 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2593
2594 // Recover resources if we crash before exiting this function.
2595 llvm::CrashRecoveryContextCleanupRegistrar<
2596 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2597
Douglas Gregorabc563f2010-07-19 21:46:24 +00002598 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2599 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2600 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002601 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002602 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2603 Buffer));
Douglas Gregorabc563f2010-07-19 21:46:24 +00002604 }
2605
Ted Kremenek4ee99262011-03-22 20:16:19 +00002606 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2607 RemappedFiles->size()))
Douglas Gregor593b0c12010-09-23 18:47:53 +00002608 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002609}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002610
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002611int clang_reparseTranslationUnit(CXTranslationUnit TU,
2612 unsigned num_unsaved_files,
2613 struct CXUnsavedFile *unsaved_files,
2614 unsigned options) {
2615 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2616 options, 0 };
2617 llvm::CrashRecoveryContext CRC;
2618
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002619 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002620 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002621 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002622 return 1;
2623 }
2624
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002625
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002626 return RTUI.result;
2627}
2628
Douglas Gregordf95a132010-08-09 20:45:32 +00002629
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002630CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002631 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002632 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002633
Ted Kremeneka60ed472010-11-16 08:15:36 +00002634 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002635 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002636}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002637
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002638CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002639 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002640 return Result;
2641}
2642
Ted Kremenekfb480492010-01-13 21:46:36 +00002643} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002644
Ted Kremenekfb480492010-01-13 21:46:36 +00002645//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002646// CXSourceLocation and CXSourceRange Operations.
2647//===----------------------------------------------------------------------===//
2648
Douglas Gregorb9790342010-01-22 21:44:22 +00002649extern "C" {
2650CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002651 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002652 return Result;
2653}
2654
2655unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002656 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2657 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2658 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002659}
2660
2661CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2662 CXFile file,
2663 unsigned line,
2664 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002665 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002666 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002667
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002668 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002669 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002670 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002671 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002672 = CXXUnit->getSourceManager().getLocation(File, line, column);
2673 if (SLoc.isInvalid()) {
2674 if (Logging)
2675 llvm::errs() << "clang_getLocation(\"" << File->getName()
2676 << "\", " << line << ", " << column << ") = invalid\n";
2677 return clang_getNullLocation();
2678 }
2679
2680 if (Logging)
2681 llvm::errs() << "clang_getLocation(\"" << File->getName()
2682 << "\", " << line << ", " << column << ") = "
2683 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002684
2685 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2686}
2687
2688CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2689 CXFile file,
2690 unsigned offset) {
2691 if (!tu || !file)
2692 return clang_getNullLocation();
2693
Ted Kremeneka60ed472010-11-16 08:15:36 +00002694 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002695 SourceLocation Start
2696 = CXXUnit->getSourceManager().getLocation(
2697 static_cast<const FileEntry *>(file),
2698 1, 1);
2699 if (Start.isInvalid()) return clang_getNullLocation();
2700
2701 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2702
2703 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002704
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002705 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002706}
2707
Douglas Gregor5352ac02010-01-28 00:27:43 +00002708CXSourceRange clang_getNullRange() {
2709 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2710 return Result;
2711}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002712
Douglas Gregor5352ac02010-01-28 00:27:43 +00002713CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2714 if (begin.ptr_data[0] != end.ptr_data[0] ||
2715 begin.ptr_data[1] != end.ptr_data[1])
2716 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002717
2718 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002719 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002720 return Result;
2721}
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002722} // end: extern "C"
Douglas Gregorb9790342010-01-22 21:44:22 +00002723
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002724static void createNullLocation(CXFile *file, unsigned *line,
2725 unsigned *column, unsigned *offset) {
2726 if (file)
2727 *file = 0;
2728 if (line)
2729 *line = 0;
2730 if (column)
2731 *column = 0;
2732 if (offset)
2733 *offset = 0;
2734 return;
2735}
2736
2737extern "C" {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002738void clang_getInstantiationLocation(CXSourceLocation location,
2739 CXFile *file,
2740 unsigned *line,
2741 unsigned *column,
2742 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002743 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2744
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002745 if (!location.ptr_data[0] || Loc.isInvalid()) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002746 createNullLocation(file, line, column, offset);
Douglas Gregor46766dc2010-01-26 19:19:08 +00002747 return;
2748 }
2749
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002750 const SourceManager &SM =
2751 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002752 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002753
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002754 // Check that the FileID is invalid on the instantiation location.
2755 // This can manifest in invalid code.
2756 FileID fileID = SM.getFileID(InstLoc);
2757 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID);
2758 if (!sloc.isFile()) {
2759 createNullLocation(file, line, column, offset);
2760 return;
2761 }
2762
Douglas Gregor1db19de2010-01-19 21:36:55 +00002763 if (file)
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002764 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002765 if (line)
2766 *line = SM.getInstantiationLineNumber(InstLoc);
2767 if (column)
2768 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002769 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002770 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002771}
2772
Douglas Gregora9b06d42010-11-09 06:24:54 +00002773void clang_getSpellingLocation(CXSourceLocation location,
2774 CXFile *file,
2775 unsigned *line,
2776 unsigned *column,
2777 unsigned *offset) {
2778 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2779
2780 if (!location.ptr_data[0] || Loc.isInvalid()) {
2781 if (file)
2782 *file = 0;
2783 if (line)
2784 *line = 0;
2785 if (column)
2786 *column = 0;
2787 if (offset)
2788 *offset = 0;
2789 return;
2790 }
2791
2792 const SourceManager &SM =
2793 *static_cast<const SourceManager*>(location.ptr_data[0]);
2794 SourceLocation SpellLoc = Loc;
2795 if (SpellLoc.isMacroID()) {
2796 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2797 if (SimpleSpellingLoc.isFileID() &&
2798 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2799 SpellLoc = SimpleSpellingLoc;
2800 else
2801 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2802 }
2803
2804 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2805 FileID FID = LocInfo.first;
2806 unsigned FileOffset = LocInfo.second;
2807
2808 if (file)
2809 *file = (void *)SM.getFileEntryForID(FID);
2810 if (line)
2811 *line = SM.getLineNumber(FID, FileOffset);
2812 if (column)
2813 *column = SM.getColumnNumber(FID, FileOffset);
2814 if (offset)
2815 *offset = FileOffset;
2816}
2817
Douglas Gregor1db19de2010-01-19 21:36:55 +00002818CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002819 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002820 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002821 return Result;
2822}
2823
2824CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002825 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002826 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002827 return Result;
2828}
2829
Douglas Gregorb9790342010-01-22 21:44:22 +00002830} // end: extern "C"
2831
Douglas Gregor1db19de2010-01-19 21:36:55 +00002832//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002833// CXFile Operations.
2834//===----------------------------------------------------------------------===//
2835
2836extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002837CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002838 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002839 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002840
Steve Naroff88145032009-10-27 14:35:18 +00002841 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002842 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002843}
2844
2845time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002846 if (!SFile)
2847 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002848
Steve Naroff88145032009-10-27 14:35:18 +00002849 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2850 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002851}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002852
Douglas Gregorb9790342010-01-22 21:44:22 +00002853CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2854 if (!tu)
2855 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002856
Ted Kremeneka60ed472010-11-16 08:15:36 +00002857 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002858
Douglas Gregorb9790342010-01-22 21:44:22 +00002859 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002860 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002861}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002862
Ted Kremenekfb480492010-01-13 21:46:36 +00002863} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002864
Ted Kremenekfb480492010-01-13 21:46:36 +00002865//===----------------------------------------------------------------------===//
2866// CXCursor Operations.
2867//===----------------------------------------------------------------------===//
2868
Ted Kremenekfb480492010-01-13 21:46:36 +00002869static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002870 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2871 return getDeclFromExpr(CE->getSubExpr());
2872
Ted Kremenekfb480492010-01-13 21:46:36 +00002873 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2874 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002875 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2876 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002877 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2878 return ME->getMemberDecl();
2879 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2880 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002881 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002882 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002883
Ted Kremenekfb480492010-01-13 21:46:36 +00002884 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2885 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002886 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2887 if (!CE->isElidable())
2888 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002889 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2890 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002891
Douglas Gregordb1314e2010-10-01 21:11:22 +00002892 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2893 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002894 if (SubstNonTypeTemplateParmPackExpr *NTTP
2895 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2896 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002897 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2898 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2899 isa<ParmVarDecl>(SizeOfPack->getPack()))
2900 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002901
Ted Kremenekfb480492010-01-13 21:46:36 +00002902 return 0;
2903}
2904
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002905static SourceLocation getLocationFromExpr(Expr *E) {
2906 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2907 return /*FIXME:*/Msg->getLeftLoc();
2908 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2909 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002910 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2911 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002912 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2913 return Member->getMemberLoc();
2914 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2915 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002916 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2917 return SizeOfPack->getPackLoc();
2918
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002919 return E->getLocStart();
2920}
2921
Ted Kremenekfb480492010-01-13 21:46:36 +00002922extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002923
2924unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002925 CXCursorVisitor visitor,
2926 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002927 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00002928 getCursorASTUnit(parent)->getMaxPCHLevel(),
2929 false);
Douglas Gregorb1373d02010-01-20 20:59:29 +00002930 return CursorVis.VisitChildren(parent);
2931}
2932
David Chisnall3387c652010-11-03 14:12:26 +00002933#ifndef __has_feature
2934#define __has_feature(x) 0
2935#endif
2936#if __has_feature(blocks)
2937typedef enum CXChildVisitResult
2938 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2939
2940static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2941 CXClientData client_data) {
2942 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2943 return block(cursor, parent);
2944}
2945#else
2946// If we are compiled with a compiler that doesn't have native blocks support,
2947// define and call the block manually, so the
2948typedef struct _CXChildVisitResult
2949{
2950 void *isa;
2951 int flags;
2952 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002953 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2954 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002955} *CXCursorVisitorBlock;
2956
2957static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2958 CXClientData client_data) {
2959 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2960 return block->invoke(block, cursor, parent);
2961}
2962#endif
2963
2964
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002965unsigned clang_visitChildrenWithBlock(CXCursor parent,
2966 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002967 return clang_visitChildren(parent, visitWithBlock, block);
2968}
2969
Douglas Gregor78205d42010-01-20 21:45:58 +00002970static CXString getDeclSpelling(Decl *D) {
2971 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00002972 if (!ND) {
2973 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2974 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2975 return createCXString(Property->getIdentifier()->getName());
2976
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002977 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00002978 }
2979
Douglas Gregor78205d42010-01-20 21:45:58 +00002980 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002981 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002982
Douglas Gregor78205d42010-01-20 21:45:58 +00002983 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2984 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2985 // and returns different names. NamedDecl returns the class name and
2986 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002987 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002988
Douglas Gregor0a35bce2010-09-01 03:07:18 +00002989 if (isa<UsingDirectiveDecl>(D))
2990 return createCXString("");
2991
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00002992 llvm::SmallString<1024> S;
2993 llvm::raw_svector_ostream os(S);
2994 ND->printName(os);
2995
2996 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00002997}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002998
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002999CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003000 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003001 return clang_getTranslationUnitSpelling(
3002 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003003
Steve Narofff334b4e2009-09-02 18:26:48 +00003004 if (clang_isReference(C.kind)) {
3005 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00003006 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00003007 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003008 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003009 }
3010 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00003011 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003012 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003013 }
3014 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00003015 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00003016 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003017 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003018 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00003019 case CXCursor_CXXBaseSpecifier: {
3020 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3021 return createCXString(B->getType().getAsString());
3022 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003023 case CXCursor_TypeRef: {
3024 TypeDecl *Type = getCursorTypeRef(C).first;
3025 assert(Type && "Missing type decl");
3026
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003027 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3028 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003029 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003030 case CXCursor_TemplateRef: {
3031 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00003032 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003033
3034 return createCXString(Template->getNameAsString());
3035 }
Douglas Gregor69319002010-08-31 23:48:11 +00003036
3037 case CXCursor_NamespaceRef: {
3038 NamedDecl *NS = getCursorNamespaceRef(C).first;
3039 assert(NS && "Missing namespace decl");
3040
3041 return createCXString(NS->getNameAsString());
3042 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003043
Douglas Gregora67e03f2010-09-09 21:42:20 +00003044 case CXCursor_MemberRef: {
3045 FieldDecl *Field = getCursorMemberRef(C).first;
3046 assert(Field && "Missing member decl");
3047
3048 return createCXString(Field->getNameAsString());
3049 }
3050
Douglas Gregor36897b02010-09-10 00:22:18 +00003051 case CXCursor_LabelRef: {
3052 LabelStmt *Label = getCursorLabelRef(C).first;
3053 assert(Label && "Missing label");
3054
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003055 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003056 }
3057
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003058 case CXCursor_OverloadedDeclRef: {
3059 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3060 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3061 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3062 return createCXString(ND->getNameAsString());
3063 return createCXString("");
3064 }
3065 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3066 return createCXString(E->getName().getAsString());
3067 OverloadedTemplateStorage *Ovl
3068 = Storage.get<OverloadedTemplateStorage*>();
3069 if (Ovl->size() == 0)
3070 return createCXString("");
3071 return createCXString((*Ovl->begin())->getNameAsString());
3072 }
3073
Daniel Dunbaracca7252009-11-30 20:42:49 +00003074 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003075 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003076 }
3077 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003078
3079 if (clang_isExpression(C.kind)) {
3080 Decl *D = getDeclFromExpr(getCursorExpr(C));
3081 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003082 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003083 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003084 }
3085
Douglas Gregor36897b02010-09-10 00:22:18 +00003086 if (clang_isStatement(C.kind)) {
3087 Stmt *S = getCursorStmt(C);
3088 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003089 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003090
3091 return createCXString("");
3092 }
3093
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003094 if (C.kind == CXCursor_MacroInstantiation)
3095 return createCXString(getCursorMacroInstantiation(C)->getName()
3096 ->getNameStart());
3097
Douglas Gregor572feb22010-03-18 18:04:21 +00003098 if (C.kind == CXCursor_MacroDefinition)
3099 return createCXString(getCursorMacroDefinition(C)->getName()
3100 ->getNameStart());
3101
Douglas Gregorecdcb882010-10-20 22:00:55 +00003102 if (C.kind == CXCursor_InclusionDirective)
3103 return createCXString(getCursorInclusionDirective(C)->getFileName());
3104
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003105 if (clang_isDeclaration(C.kind))
3106 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003107
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003108 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003109}
3110
Douglas Gregor358559d2010-10-02 22:49:11 +00003111CXString clang_getCursorDisplayName(CXCursor C) {
3112 if (!clang_isDeclaration(C.kind))
3113 return clang_getCursorSpelling(C);
3114
3115 Decl *D = getCursorDecl(C);
3116 if (!D)
3117 return createCXString("");
3118
3119 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3120 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3121 D = FunTmpl->getTemplatedDecl();
3122
3123 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3124 llvm::SmallString<64> Str;
3125 llvm::raw_svector_ostream OS(Str);
3126 OS << Function->getNameAsString();
3127 if (Function->getPrimaryTemplate())
3128 OS << "<>";
3129 OS << "(";
3130 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3131 if (I)
3132 OS << ", ";
3133 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3134 }
3135
3136 if (Function->isVariadic()) {
3137 if (Function->getNumParams())
3138 OS << ", ";
3139 OS << "...";
3140 }
3141 OS << ")";
3142 return createCXString(OS.str());
3143 }
3144
3145 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3146 llvm::SmallString<64> Str;
3147 llvm::raw_svector_ostream OS(Str);
3148 OS << ClassTemplate->getNameAsString();
3149 OS << "<";
3150 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3151 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3152 if (I)
3153 OS << ", ";
3154
3155 NamedDecl *Param = Params->getParam(I);
3156 if (Param->getIdentifier()) {
3157 OS << Param->getIdentifier()->getName();
3158 continue;
3159 }
3160
3161 // There is no parameter name, which makes this tricky. Try to come up
3162 // with something useful that isn't too long.
3163 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3164 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3165 else if (NonTypeTemplateParmDecl *NTTP
3166 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3167 OS << NTTP->getType().getAsString(Policy);
3168 else
3169 OS << "template<...> class";
3170 }
3171
3172 OS << ">";
3173 return createCXString(OS.str());
3174 }
3175
3176 if (ClassTemplateSpecializationDecl *ClassSpec
3177 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3178 // If the type was explicitly written, use that.
3179 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3180 return createCXString(TSInfo->getType().getAsString(Policy));
3181
3182 llvm::SmallString<64> Str;
3183 llvm::raw_svector_ostream OS(Str);
3184 OS << ClassSpec->getNameAsString();
3185 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003186 ClassSpec->getTemplateArgs().data(),
3187 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003188 Policy);
3189 return createCXString(OS.str());
3190 }
3191
3192 return clang_getCursorSpelling(C);
3193}
3194
Ted Kremeneke68fff62010-02-17 00:41:32 +00003195CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003196 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003197 case CXCursor_FunctionDecl:
3198 return createCXString("FunctionDecl");
3199 case CXCursor_TypedefDecl:
3200 return createCXString("TypedefDecl");
3201 case CXCursor_EnumDecl:
3202 return createCXString("EnumDecl");
3203 case CXCursor_EnumConstantDecl:
3204 return createCXString("EnumConstantDecl");
3205 case CXCursor_StructDecl:
3206 return createCXString("StructDecl");
3207 case CXCursor_UnionDecl:
3208 return createCXString("UnionDecl");
3209 case CXCursor_ClassDecl:
3210 return createCXString("ClassDecl");
3211 case CXCursor_FieldDecl:
3212 return createCXString("FieldDecl");
3213 case CXCursor_VarDecl:
3214 return createCXString("VarDecl");
3215 case CXCursor_ParmDecl:
3216 return createCXString("ParmDecl");
3217 case CXCursor_ObjCInterfaceDecl:
3218 return createCXString("ObjCInterfaceDecl");
3219 case CXCursor_ObjCCategoryDecl:
3220 return createCXString("ObjCCategoryDecl");
3221 case CXCursor_ObjCProtocolDecl:
3222 return createCXString("ObjCProtocolDecl");
3223 case CXCursor_ObjCPropertyDecl:
3224 return createCXString("ObjCPropertyDecl");
3225 case CXCursor_ObjCIvarDecl:
3226 return createCXString("ObjCIvarDecl");
3227 case CXCursor_ObjCInstanceMethodDecl:
3228 return createCXString("ObjCInstanceMethodDecl");
3229 case CXCursor_ObjCClassMethodDecl:
3230 return createCXString("ObjCClassMethodDecl");
3231 case CXCursor_ObjCImplementationDecl:
3232 return createCXString("ObjCImplementationDecl");
3233 case CXCursor_ObjCCategoryImplDecl:
3234 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003235 case CXCursor_CXXMethod:
3236 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003237 case CXCursor_UnexposedDecl:
3238 return createCXString("UnexposedDecl");
3239 case CXCursor_ObjCSuperClassRef:
3240 return createCXString("ObjCSuperClassRef");
3241 case CXCursor_ObjCProtocolRef:
3242 return createCXString("ObjCProtocolRef");
3243 case CXCursor_ObjCClassRef:
3244 return createCXString("ObjCClassRef");
3245 case CXCursor_TypeRef:
3246 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003247 case CXCursor_TemplateRef:
3248 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003249 case CXCursor_NamespaceRef:
3250 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003251 case CXCursor_MemberRef:
3252 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003253 case CXCursor_LabelRef:
3254 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003255 case CXCursor_OverloadedDeclRef:
3256 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003257 case CXCursor_UnexposedExpr:
3258 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003259 case CXCursor_BlockExpr:
3260 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003261 case CXCursor_DeclRefExpr:
3262 return createCXString("DeclRefExpr");
3263 case CXCursor_MemberRefExpr:
3264 return createCXString("MemberRefExpr");
3265 case CXCursor_CallExpr:
3266 return createCXString("CallExpr");
3267 case CXCursor_ObjCMessageExpr:
3268 return createCXString("ObjCMessageExpr");
3269 case CXCursor_UnexposedStmt:
3270 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003271 case CXCursor_LabelStmt:
3272 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003273 case CXCursor_InvalidFile:
3274 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003275 case CXCursor_InvalidCode:
3276 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003277 case CXCursor_NoDeclFound:
3278 return createCXString("NoDeclFound");
3279 case CXCursor_NotImplemented:
3280 return createCXString("NotImplemented");
3281 case CXCursor_TranslationUnit:
3282 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003283 case CXCursor_UnexposedAttr:
3284 return createCXString("UnexposedAttr");
3285 case CXCursor_IBActionAttr:
3286 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003287 case CXCursor_IBOutletAttr:
3288 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003289 case CXCursor_IBOutletCollectionAttr:
3290 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003291 case CXCursor_PreprocessingDirective:
3292 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003293 case CXCursor_MacroDefinition:
3294 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003295 case CXCursor_MacroInstantiation:
3296 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003297 case CXCursor_InclusionDirective:
3298 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003299 case CXCursor_Namespace:
3300 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003301 case CXCursor_LinkageSpec:
3302 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003303 case CXCursor_CXXBaseSpecifier:
3304 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003305 case CXCursor_Constructor:
3306 return createCXString("CXXConstructor");
3307 case CXCursor_Destructor:
3308 return createCXString("CXXDestructor");
3309 case CXCursor_ConversionFunction:
3310 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003311 case CXCursor_TemplateTypeParameter:
3312 return createCXString("TemplateTypeParameter");
3313 case CXCursor_NonTypeTemplateParameter:
3314 return createCXString("NonTypeTemplateParameter");
3315 case CXCursor_TemplateTemplateParameter:
3316 return createCXString("TemplateTemplateParameter");
3317 case CXCursor_FunctionTemplate:
3318 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003319 case CXCursor_ClassTemplate:
3320 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003321 case CXCursor_ClassTemplatePartialSpecialization:
3322 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003323 case CXCursor_NamespaceAlias:
3324 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003325 case CXCursor_UsingDirective:
3326 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003327 case CXCursor_UsingDeclaration:
3328 return createCXString("UsingDeclaration");
Steve Naroff89922f82009-08-31 00:59:03 +00003329 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003330
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003331 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003332 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003333}
Steve Naroff89922f82009-08-31 00:59:03 +00003334
Ted Kremeneke68fff62010-02-17 00:41:32 +00003335enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3336 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003337 CXClientData client_data) {
3338 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003339
3340 // If our current best cursor is the construction of a temporary object,
3341 // don't replace that cursor with a type reference, because we want
3342 // clang_getCursor() to point at the constructor.
3343 if (clang_isExpression(BestCursor->kind) &&
3344 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3345 cursor.kind == CXCursor_TypeRef)
3346 return CXChildVisit_Recurse;
3347
Douglas Gregor85fe1562010-12-10 07:23:11 +00003348 // Don't override a preprocessing cursor with another preprocessing
3349 // cursor; we want the outermost preprocessing cursor.
3350 if (clang_isPreprocessing(cursor.kind) &&
3351 clang_isPreprocessing(BestCursor->kind))
3352 return CXChildVisit_Recurse;
3353
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003354 *BestCursor = cursor;
3355 return CXChildVisit_Recurse;
3356}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003357
Douglas Gregorb9790342010-01-22 21:44:22 +00003358CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3359 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003360 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003361
Ted Kremeneka60ed472010-11-16 08:15:36 +00003362 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003363 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3364
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003365 // Translate the given source location to make it point at the beginning of
3366 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003367 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003368
3369 // Guard against an invalid SourceLocation, or we may assert in one
3370 // of the following calls.
3371 if (SLoc.isInvalid())
3372 return clang_getNullCursor();
3373
Douglas Gregor40749ee2010-11-03 00:35:38 +00003374 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003375 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3376 CXXUnit->getASTContext().getLangOptions());
3377
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003378 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3379 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003380 // FIXME: Would be great to have a "hint" cursor, then walk from that
3381 // hint cursor upward until we find a cursor whose source range encloses
3382 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003383 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3384 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00003385 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003386 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003387 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003388
3389 if (Logging) {
3390 CXFile SearchFile;
3391 unsigned SearchLine, SearchColumn;
3392 CXFile ResultFile;
3393 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003394 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3395 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003396 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3397
3398 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3399 0);
3400 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3401 &ResultColumn, 0);
3402 SearchFileName = clang_getFileName(SearchFile);
3403 ResultFileName = clang_getFileName(ResultFile);
3404 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003405 USR = clang_getCursorUSR(Result);
3406 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003407 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3408 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003409 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3410 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003411 clang_disposeString(SearchFileName);
3412 clang_disposeString(ResultFileName);
3413 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003414 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003415
3416 CXCursor Definition = clang_getCursorDefinition(Result);
3417 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3418 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3419 CXString DefinitionKindSpelling
3420 = clang_getCursorKindSpelling(Definition.kind);
3421 CXFile DefinitionFile;
3422 unsigned DefinitionLine, DefinitionColumn;
3423 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3424 &DefinitionLine, &DefinitionColumn, 0);
3425 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3426 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3427 clang_getCString(DefinitionKindSpelling),
3428 clang_getCString(DefinitionFileName),
3429 DefinitionLine, DefinitionColumn);
3430 clang_disposeString(DefinitionFileName);
3431 clang_disposeString(DefinitionKindSpelling);
3432 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003433 }
3434
Ted Kremeneke68fff62010-02-17 00:41:32 +00003435 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003436}
3437
Ted Kremenek73885552009-11-17 19:28:59 +00003438CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003439 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003440}
3441
3442unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003443 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003444}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003445
Douglas Gregor9ce55842010-11-20 00:09:34 +00003446unsigned clang_hashCursor(CXCursor C) {
3447 unsigned Index = 0;
3448 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3449 Index = 1;
3450
3451 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3452 std::make_pair(C.kind, C.data[Index]));
3453}
3454
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003455unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003456 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3457}
3458
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003459unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003460 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3461}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003462
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003463unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003464 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3465}
3466
Douglas Gregor97b98722010-01-19 23:20:36 +00003467unsigned clang_isExpression(enum CXCursorKind K) {
3468 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3469}
3470
3471unsigned clang_isStatement(enum CXCursorKind K) {
3472 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3473}
3474
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003475unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3476 return K == CXCursor_TranslationUnit;
3477}
3478
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003479unsigned clang_isPreprocessing(enum CXCursorKind K) {
3480 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3481}
3482
Ted Kremenekad6eff62010-03-08 21:17:29 +00003483unsigned clang_isUnexposed(enum CXCursorKind K) {
3484 switch (K) {
3485 case CXCursor_UnexposedDecl:
3486 case CXCursor_UnexposedExpr:
3487 case CXCursor_UnexposedStmt:
3488 case CXCursor_UnexposedAttr:
3489 return true;
3490 default:
3491 return false;
3492 }
3493}
3494
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003495CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003496 return C.kind;
3497}
3498
Douglas Gregor98258af2010-01-18 22:46:11 +00003499CXSourceLocation clang_getCursorLocation(CXCursor C) {
3500 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003501 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003502 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003503 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3504 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003505 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003506 }
3507
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003508 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003509 std::pair<ObjCProtocolDecl *, SourceLocation> P
3510 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003511 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003512 }
3513
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003514 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003515 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3516 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003517 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003518 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003519
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003520 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003521 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003522 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003523 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003524
3525 case CXCursor_TemplateRef: {
3526 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3527 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3528 }
3529
Douglas Gregor69319002010-08-31 23:48:11 +00003530 case CXCursor_NamespaceRef: {
3531 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3532 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3533 }
3534
Douglas Gregora67e03f2010-09-09 21:42:20 +00003535 case CXCursor_MemberRef: {
3536 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3537 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3538 }
3539
Ted Kremenek3064ef92010-08-27 21:34:58 +00003540 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003541 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3542 if (!BaseSpec)
3543 return clang_getNullLocation();
3544
3545 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3546 return cxloc::translateSourceLocation(getCursorContext(C),
3547 TSInfo->getTypeLoc().getBeginLoc());
3548
3549 return cxloc::translateSourceLocation(getCursorContext(C),
3550 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003551 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003552
Douglas Gregor36897b02010-09-10 00:22:18 +00003553 case CXCursor_LabelRef: {
3554 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3555 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3556 }
3557
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003558 case CXCursor_OverloadedDeclRef:
3559 return cxloc::translateSourceLocation(getCursorContext(C),
3560 getCursorOverloadedDeclRef(C).second);
3561
Douglas Gregorf46034a2010-01-18 23:41:10 +00003562 default:
3563 // FIXME: Need a way to enumerate all non-reference cases.
3564 llvm_unreachable("Missed a reference kind");
3565 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003566 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003567
3568 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003569 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003570 getLocationFromExpr(getCursorExpr(C)));
3571
Douglas Gregor36897b02010-09-10 00:22:18 +00003572 if (clang_isStatement(C.kind))
3573 return cxloc::translateSourceLocation(getCursorContext(C),
3574 getCursorStmt(C)->getLocStart());
3575
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003576 if (C.kind == CXCursor_PreprocessingDirective) {
3577 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3578 return cxloc::translateSourceLocation(getCursorContext(C), L);
3579 }
Douglas Gregor48072312010-03-18 15:23:44 +00003580
3581 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003582 SourceLocation L
3583 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003584 return cxloc::translateSourceLocation(getCursorContext(C), L);
3585 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003586
3587 if (C.kind == CXCursor_MacroDefinition) {
3588 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3589 return cxloc::translateSourceLocation(getCursorContext(C), L);
3590 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003591
3592 if (C.kind == CXCursor_InclusionDirective) {
3593 SourceLocation L
3594 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3595 return cxloc::translateSourceLocation(getCursorContext(C), L);
3596 }
3597
Ted Kremenek9a700d22010-05-12 06:16:13 +00003598 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003599 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003600
Douglas Gregorf46034a2010-01-18 23:41:10 +00003601 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003602 SourceLocation Loc = D->getLocation();
3603 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3604 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003605 // FIXME: Multiple variables declared in a single declaration
3606 // currently lack the information needed to correctly determine their
3607 // ranges when accounting for the type-specifier. We use context
3608 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3609 // and if so, whether it is the first decl.
3610 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3611 if (!cxcursor::isFirstInDeclGroup(C))
3612 Loc = VD->getLocation();
3613 }
3614
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003615 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003616}
Douglas Gregora7bde202010-01-19 00:34:46 +00003617
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003618} // end extern "C"
3619
3620static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003621 if (clang_isReference(C.kind)) {
3622 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003623 case CXCursor_ObjCSuperClassRef:
3624 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003625
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003626 case CXCursor_ObjCProtocolRef:
3627 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003628
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003629 case CXCursor_ObjCClassRef:
3630 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003631
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003632 case CXCursor_TypeRef:
3633 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003634
3635 case CXCursor_TemplateRef:
3636 return getCursorTemplateRef(C).second;
3637
Douglas Gregor69319002010-08-31 23:48:11 +00003638 case CXCursor_NamespaceRef:
3639 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003640
3641 case CXCursor_MemberRef:
3642 return getCursorMemberRef(C).second;
3643
Ted Kremenek3064ef92010-08-27 21:34:58 +00003644 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003645 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003646
Douglas Gregor36897b02010-09-10 00:22:18 +00003647 case CXCursor_LabelRef:
3648 return getCursorLabelRef(C).second;
3649
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003650 case CXCursor_OverloadedDeclRef:
3651 return getCursorOverloadedDeclRef(C).second;
3652
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003653 default:
3654 // FIXME: Need a way to enumerate all non-reference cases.
3655 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003656 }
3657 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003658
3659 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003660 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003661
3662 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003663 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003664
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003665 if (C.kind == CXCursor_PreprocessingDirective)
3666 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003667
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003668 if (C.kind == CXCursor_MacroInstantiation)
3669 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003670
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003671 if (C.kind == CXCursor_MacroDefinition)
3672 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003673
3674 if (C.kind == CXCursor_InclusionDirective)
3675 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3676
Ted Kremenek007a7c92010-11-01 23:26:51 +00003677 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3678 Decl *D = cxcursor::getCursorDecl(C);
3679 SourceRange R = D->getSourceRange();
3680 // FIXME: Multiple variables declared in a single declaration
3681 // currently lack the information needed to correctly determine their
3682 // ranges when accounting for the type-specifier. We use context
3683 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3684 // and if so, whether it is the first decl.
3685 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3686 if (!cxcursor::isFirstInDeclGroup(C))
3687 R.setBegin(VD->getLocation());
3688 }
3689 return R;
3690 }
Douglas Gregor66537982010-11-17 17:14:07 +00003691 return SourceRange();
3692}
3693
3694/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3695/// the decl-specifier-seq for declarations.
3696static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3697 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3698 Decl *D = cxcursor::getCursorDecl(C);
3699 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003700
Douglas Gregor2494dd02011-03-01 01:34:45 +00003701 // Adjust the start of the location for declarations preceded by
3702 // declaration specifiers.
3703 SourceLocation StartLoc;
3704 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3705 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3706 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3707 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3708 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3709 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3710 }
3711
3712 if (StartLoc.isValid() && R.getBegin().isValid() &&
3713 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3714 R.setBegin(StartLoc);
3715
3716 // FIXME: Multiple variables declared in a single declaration
3717 // currently lack the information needed to correctly determine their
3718 // ranges when accounting for the type-specifier. We use context
3719 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3720 // and if so, whether it is the first decl.
3721 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3722 if (!cxcursor::isFirstInDeclGroup(C))
3723 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003724 }
3725
3726 return R;
3727 }
3728
3729 return getRawCursorExtent(C);
3730}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003731
3732extern "C" {
3733
3734CXSourceRange clang_getCursorExtent(CXCursor C) {
3735 SourceRange R = getRawCursorExtent(C);
3736 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003737 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003738
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003739 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003740}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003741
3742CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003743 if (clang_isInvalid(C.kind))
3744 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003745
Ted Kremeneka60ed472010-11-16 08:15:36 +00003746 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003747 if (clang_isDeclaration(C.kind)) {
3748 Decl *D = getCursorDecl(C);
3749 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003750 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003751 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003752 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003753 if (ObjCForwardProtocolDecl *Protocols
3754 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003755 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003756 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3757 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3758 return MakeCXCursor(Property, tu);
3759
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003760 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003761 }
3762
Douglas Gregor97b98722010-01-19 23:20:36 +00003763 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003764 Expr *E = getCursorExpr(C);
3765 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003766 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003767 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003768
3769 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003770 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003771
Douglas Gregor97b98722010-01-19 23:20:36 +00003772 return clang_getNullCursor();
3773 }
3774
Douglas Gregor36897b02010-09-10 00:22:18 +00003775 if (clang_isStatement(C.kind)) {
3776 Stmt *S = getCursorStmt(C);
3777 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek37c2e962011-03-15 23:47:49 +00003778 if (LabelDecl *label = Goto->getLabel())
3779 if (LabelStmt *labelS = label->getStmt())
3780 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003781
3782 return clang_getNullCursor();
3783 }
3784
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003785 if (C.kind == CXCursor_MacroInstantiation) {
3786 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003787 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003788 }
3789
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003790 if (!clang_isReference(C.kind))
3791 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003792
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003793 switch (C.kind) {
3794 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003795 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003796
3797 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003798 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003799
3800 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003801 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003802
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003803 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003804 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003805
3806 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003807 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003808
Douglas Gregor69319002010-08-31 23:48:11 +00003809 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003810 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003811
Douglas Gregora67e03f2010-09-09 21:42:20 +00003812 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003813 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003814
Ted Kremenek3064ef92010-08-27 21:34:58 +00003815 case CXCursor_CXXBaseSpecifier: {
3816 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3817 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003818 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003819 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003820
Douglas Gregor36897b02010-09-10 00:22:18 +00003821 case CXCursor_LabelRef:
3822 // FIXME: We end up faking the "parent" declaration here because we
3823 // don't want to make CXCursor larger.
3824 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003825 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3826 .getTranslationUnitDecl(),
3827 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003828
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003829 case CXCursor_OverloadedDeclRef:
3830 return C;
3831
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003832 default:
3833 // We would prefer to enumerate all non-reference cursor kinds here.
3834 llvm_unreachable("Unhandled reference cursor kind");
3835 break;
3836 }
3837 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003838
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003839 return clang_getNullCursor();
3840}
3841
Douglas Gregorb6998662010-01-19 19:34:47 +00003842CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003843 if (clang_isInvalid(C.kind))
3844 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003845
Ted Kremeneka60ed472010-11-16 08:15:36 +00003846 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003847
Douglas Gregorb6998662010-01-19 19:34:47 +00003848 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003849 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003850 C = clang_getCursorReferenced(C);
3851 WasReference = true;
3852 }
3853
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003854 if (C.kind == CXCursor_MacroInstantiation)
3855 return clang_getCursorReferenced(C);
3856
Douglas Gregorb6998662010-01-19 19:34:47 +00003857 if (!clang_isDeclaration(C.kind))
3858 return clang_getNullCursor();
3859
3860 Decl *D = getCursorDecl(C);
3861 if (!D)
3862 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003863
Douglas Gregorb6998662010-01-19 19:34:47 +00003864 switch (D->getKind()) {
3865 // Declaration kinds that don't really separate the notions of
3866 // declaration and definition.
3867 case Decl::Namespace:
3868 case Decl::Typedef:
3869 case Decl::TemplateTypeParm:
3870 case Decl::EnumConstant:
3871 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003872 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003873 case Decl::ObjCIvar:
3874 case Decl::ObjCAtDefsField:
3875 case Decl::ImplicitParam:
3876 case Decl::ParmVar:
3877 case Decl::NonTypeTemplateParm:
3878 case Decl::TemplateTemplateParm:
3879 case Decl::ObjCCategoryImpl:
3880 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003881 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003882 case Decl::LinkageSpec:
3883 case Decl::ObjCPropertyImpl:
3884 case Decl::FileScopeAsm:
3885 case Decl::StaticAssert:
3886 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003887 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003888 return C;
3889
3890 // Declaration kinds that don't make any sense here, but are
3891 // nonetheless harmless.
3892 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003893 break;
3894
3895 // Declaration kinds for which the definition is not resolvable.
3896 case Decl::UnresolvedUsingTypename:
3897 case Decl::UnresolvedUsingValue:
3898 break;
3899
3900 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003901 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003902 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003903
3904 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003905 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003906
3907 case Decl::Enum:
3908 case Decl::Record:
3909 case Decl::CXXRecord:
3910 case Decl::ClassTemplateSpecialization:
3911 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003912 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003913 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003914 return clang_getNullCursor();
3915
3916 case Decl::Function:
3917 case Decl::CXXMethod:
3918 case Decl::CXXConstructor:
3919 case Decl::CXXDestructor:
3920 case Decl::CXXConversion: {
3921 const FunctionDecl *Def = 0;
3922 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003923 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003924 return clang_getNullCursor();
3925 }
3926
3927 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003928 // Ask the variable if it has a definition.
3929 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003930 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003931 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003932 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003933
Douglas Gregorb6998662010-01-19 19:34:47 +00003934 case Decl::FunctionTemplate: {
3935 const FunctionDecl *Def = 0;
3936 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003937 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003938 return clang_getNullCursor();
3939 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003940
Douglas Gregorb6998662010-01-19 19:34:47 +00003941 case Decl::ClassTemplate: {
3942 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003943 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003944 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003945 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003946 return clang_getNullCursor();
3947 }
3948
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003949 case Decl::Using:
3950 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003951 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003952
3953 case Decl::UsingShadow:
3954 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003955 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003956 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003957
3958 case Decl::ObjCMethod: {
3959 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3960 if (Method->isThisDeclarationADefinition())
3961 return C;
3962
3963 // Dig out the method definition in the associated
3964 // @implementation, if we have it.
3965 // FIXME: The ASTs should make finding the definition easier.
3966 if (ObjCInterfaceDecl *Class
3967 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3968 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3969 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3970 Method->isInstanceMethod()))
3971 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003972 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003973
3974 return clang_getNullCursor();
3975 }
3976
3977 case Decl::ObjCCategory:
3978 if (ObjCCategoryImplDecl *Impl
3979 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003980 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003981 return clang_getNullCursor();
3982
3983 case Decl::ObjCProtocol:
3984 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3985 return C;
3986 return clang_getNullCursor();
3987
3988 case Decl::ObjCInterface:
3989 // There are two notions of a "definition" for an Objective-C
3990 // class: the interface and its implementation. When we resolved a
3991 // reference to an Objective-C class, produce the @interface as
3992 // the definition; when we were provided with the interface,
3993 // produce the @implementation as the definition.
3994 if (WasReference) {
3995 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
3996 return C;
3997 } else if (ObjCImplementationDecl *Impl
3998 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003999 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004000 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004001
Douglas Gregorb6998662010-01-19 19:34:47 +00004002 case Decl::ObjCProperty:
4003 // FIXME: We don't really know where to find the
4004 // ObjCPropertyImplDecls that implement this property.
4005 return clang_getNullCursor();
4006
4007 case Decl::ObjCCompatibleAlias:
4008 if (ObjCInterfaceDecl *Class
4009 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4010 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004011 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004012
Douglas Gregorb6998662010-01-19 19:34:47 +00004013 return clang_getNullCursor();
4014
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004015 case Decl::ObjCForwardProtocol:
4016 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004017 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004018
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004019 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004020 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004021 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004022
4023 case Decl::Friend:
4024 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004025 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004026 return clang_getNullCursor();
4027
4028 case Decl::FriendTemplate:
4029 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004030 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004031 return clang_getNullCursor();
4032 }
4033
4034 return clang_getNullCursor();
4035}
4036
4037unsigned clang_isCursorDefinition(CXCursor C) {
4038 if (!clang_isDeclaration(C.kind))
4039 return 0;
4040
4041 return clang_getCursorDefinition(C) == C;
4042}
4043
Douglas Gregor1a9d0502010-11-19 23:44:15 +00004044CXCursor clang_getCanonicalCursor(CXCursor C) {
4045 if (!clang_isDeclaration(C.kind))
4046 return C;
4047
4048 if (Decl *D = getCursorDecl(C))
4049 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4050
4051 return C;
4052}
4053
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004054unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004055 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004056 return 0;
4057
4058 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4059 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4060 return E->getNumDecls();
4061
4062 if (OverloadedTemplateStorage *S
4063 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4064 return S->size();
4065
4066 Decl *D = Storage.get<Decl*>();
4067 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00004068 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004069 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4070 return Classes->size();
4071 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4072 return Protocols->protocol_size();
4073
4074 return 0;
4075}
4076
4077CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004078 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004079 return clang_getNullCursor();
4080
4081 if (index >= clang_getNumOverloadedDecls(cursor))
4082 return clang_getNullCursor();
4083
Ted Kremeneka60ed472010-11-16 08:15:36 +00004084 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004085 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4086 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004087 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004088
4089 if (OverloadedTemplateStorage *S
4090 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004091 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004092
4093 Decl *D = Storage.get<Decl*>();
4094 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4095 // FIXME: This is, unfortunately, linear time.
4096 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4097 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004098 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004099 }
4100
4101 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004102 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004103
4104 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004105 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004106
4107 return clang_getNullCursor();
4108}
4109
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004110void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004111 const char **startBuf,
4112 const char **endBuf,
4113 unsigned *startLine,
4114 unsigned *startColumn,
4115 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004116 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004117 assert(getCursorDecl(C) && "CXCursor has null decl");
4118 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004119 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4120 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004121
Steve Naroff4ade6d62009-09-23 17:52:52 +00004122 SourceManager &SM = FD->getASTContext().getSourceManager();
4123 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4124 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4125 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4126 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4127 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4128 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4129}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004130
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004131void clang_enableStackTraces(void) {
4132 llvm::sys::PrintStackTraceOnErrorSignal();
4133}
4134
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004135void clang_executeOnThread(void (*fn)(void*), void *user_data,
4136 unsigned stack_size) {
4137 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4138}
4139
Ted Kremenekfb480492010-01-13 21:46:36 +00004140} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004141
Ted Kremenekfb480492010-01-13 21:46:36 +00004142//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004143// Token-based Operations.
4144//===----------------------------------------------------------------------===//
4145
4146/* CXToken layout:
4147 * int_data[0]: a CXTokenKind
4148 * int_data[1]: starting token location
4149 * int_data[2]: token length
4150 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004151 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004152 * otherwise unused.
4153 */
4154extern "C" {
4155
4156CXTokenKind clang_getTokenKind(CXToken CXTok) {
4157 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4158}
4159
4160CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4161 switch (clang_getTokenKind(CXTok)) {
4162 case CXToken_Identifier:
4163 case CXToken_Keyword:
4164 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004165 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4166 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004167
4168 case CXToken_Literal: {
4169 // We have stashed the starting pointer in the ptr_data field. Use it.
4170 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004171 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004172 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004173
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004174 case CXToken_Punctuation:
4175 case CXToken_Comment:
4176 break;
4177 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004178
4179 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004180 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004181 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004182 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004183 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004184
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004185 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4186 std::pair<FileID, unsigned> LocInfo
4187 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004188 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004189 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004190 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4191 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004192 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004193
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004194 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004195}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004196
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004197CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004198 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004199 if (!CXXUnit)
4200 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004201
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004202 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4203 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4204}
4205
4206CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004207 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004208 if (!CXXUnit)
4209 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004210
4211 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004212 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4213}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004214
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004215void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4216 CXToken **Tokens, unsigned *NumTokens) {
4217 if (Tokens)
4218 *Tokens = 0;
4219 if (NumTokens)
4220 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004221
Ted Kremeneka60ed472010-11-16 08:15:36 +00004222 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004223 if (!CXXUnit || !Tokens || !NumTokens)
4224 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004225
Douglas Gregorbdf60622010-03-05 21:16:25 +00004226 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4227
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004228 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004229 if (R.isInvalid())
4230 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004231
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004232 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4233 std::pair<FileID, unsigned> BeginLocInfo
4234 = SourceMgr.getDecomposedLoc(R.getBegin());
4235 std::pair<FileID, unsigned> EndLocInfo
4236 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004237
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004238 // Cannot tokenize across files.
4239 if (BeginLocInfo.first != EndLocInfo.first)
4240 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004241
4242 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004243 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004244 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004245 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004246 if (Invalid)
4247 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004248
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004249 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4250 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004251 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004252 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004253
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004254 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004255 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004256 llvm::SmallVector<CXToken, 32> CXTokens;
4257 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004258 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004259 do {
4260 // Lex the next token
4261 Lex.LexFromRawLexer(Tok);
4262 if (Tok.is(tok::eof))
4263 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004264
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004265 // Initialize the CXToken.
4266 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004267
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004268 // - Common fields
4269 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4270 CXTok.int_data[2] = Tok.getLength();
4271 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004272
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004273 // - Kind-specific fields
4274 if (Tok.isLiteral()) {
4275 CXTok.int_data[0] = CXToken_Literal;
4276 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004277 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004278 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004279 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004280 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004281
David Chisnall096428b2010-10-13 21:44:48 +00004282 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004283 CXTok.int_data[0] = CXToken_Keyword;
4284 }
4285 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004286 CXTok.int_data[0] = Tok.is(tok::identifier)
4287 ? CXToken_Identifier
4288 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004289 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004290 CXTok.ptr_data = II;
4291 } else if (Tok.is(tok::comment)) {
4292 CXTok.int_data[0] = CXToken_Comment;
4293 CXTok.ptr_data = 0;
4294 } else {
4295 CXTok.int_data[0] = CXToken_Punctuation;
4296 CXTok.ptr_data = 0;
4297 }
4298 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004299 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004300 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004301
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004302 if (CXTokens.empty())
4303 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004304
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004305 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4306 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4307 *NumTokens = CXTokens.size();
4308}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004309
Ted Kremenek6db61092010-05-05 00:55:15 +00004310void clang_disposeTokens(CXTranslationUnit TU,
4311 CXToken *Tokens, unsigned NumTokens) {
4312 free(Tokens);
4313}
4314
4315} // end: extern "C"
4316
4317//===----------------------------------------------------------------------===//
4318// Token annotation APIs.
4319//===----------------------------------------------------------------------===//
4320
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004321typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004322static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4323 CXCursor parent,
4324 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004325namespace {
4326class AnnotateTokensWorker {
4327 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004328 CXToken *Tokens;
4329 CXCursor *Cursors;
4330 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004331 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004332 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004333 CursorVisitor AnnotateVis;
4334 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004335 bool HasContextSensitiveKeywords;
4336
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004337 bool MoreTokens() const { return TokIdx < NumTokens; }
4338 unsigned NextToken() const { return TokIdx; }
4339 void AdvanceToken() { ++TokIdx; }
4340 SourceLocation GetTokenLoc(unsigned tokI) {
4341 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4342 }
4343
Ted Kremenek6db61092010-05-05 00:55:15 +00004344public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004345 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004346 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004347 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004348 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004349 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004350 AnnotateVis(tu,
4351 AnnotateTokensVisitor, this,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00004352 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004353 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4354 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004355
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004356 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004357 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004358 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004359 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004360 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004361 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004362
4363 /// \brief Determine whether the annotator saw any cursors that have
4364 /// context-sensitive keywords.
4365 bool hasContextSensitiveKeywords() const {
4366 return HasContextSensitiveKeywords;
4367 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004368};
4369}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004370
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004371void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4372 // Walk the AST within the region of interest, annotating tokens
4373 // along the way.
4374 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004375
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004376 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4377 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004378 if (Pos != Annotated.end() &&
4379 (clang_isInvalid(Cursors[I].kind) ||
4380 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004381 Cursors[I] = Pos->second;
4382 }
4383
4384 // Finish up annotating any tokens left.
4385 if (!MoreTokens())
4386 return;
4387
4388 const CXCursor &C = clang_getNullCursor();
4389 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4390 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4391 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004392 }
4393}
4394
Ted Kremenek6db61092010-05-05 00:55:15 +00004395enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004396AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004397 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004398 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004399 if (cursorRange.isInvalid())
4400 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004401
4402 if (!HasContextSensitiveKeywords) {
4403 // Objective-C properties can have context-sensitive keywords.
4404 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4405 if (ObjCPropertyDecl *Property
4406 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4407 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4408 }
4409 // Objective-C methods can have context-sensitive keywords.
4410 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4411 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4412 if (ObjCMethodDecl *Method
4413 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4414 if (Method->getObjCDeclQualifier())
4415 HasContextSensitiveKeywords = true;
4416 else {
4417 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4418 PEnd = Method->param_end();
4419 P != PEnd; ++P) {
4420 if ((*P)->getObjCDeclQualifier()) {
4421 HasContextSensitiveKeywords = true;
4422 break;
4423 }
4424 }
4425 }
4426 }
4427 }
4428 // C++ methods can have context-sensitive keywords.
4429 else if (cursor.kind == CXCursor_CXXMethod) {
4430 if (CXXMethodDecl *Method
4431 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4432 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4433 HasContextSensitiveKeywords = true;
4434 }
4435 }
4436 // C++ classes can have context-sensitive keywords.
4437 else if (cursor.kind == CXCursor_StructDecl ||
4438 cursor.kind == CXCursor_ClassDecl ||
4439 cursor.kind == CXCursor_ClassTemplate ||
4440 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4441 if (Decl *D = getCursorDecl(cursor))
4442 if (D->hasAttr<FinalAttr>())
4443 HasContextSensitiveKeywords = true;
4444 }
4445 }
4446
Douglas Gregor4419b672010-10-21 06:10:04 +00004447 if (clang_isPreprocessing(cursor.kind)) {
4448 // For macro instantiations, just note where the beginning of the macro
4449 // instantiation occurs.
4450 if (cursor.kind == CXCursor_MacroInstantiation) {
4451 Annotated[Loc.int_data] = cursor;
4452 return CXChildVisit_Recurse;
4453 }
4454
Douglas Gregor4419b672010-10-21 06:10:04 +00004455 // Items in the preprocessing record are kept separate from items in
4456 // declarations, so we keep a separate token index.
4457 unsigned SavedTokIdx = TokIdx;
4458 TokIdx = PreprocessingTokIdx;
4459
4460 // Skip tokens up until we catch up to the beginning of the preprocessing
4461 // entry.
4462 while (MoreTokens()) {
4463 const unsigned I = NextToken();
4464 SourceLocation TokLoc = GetTokenLoc(I);
4465 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4466 case RangeBefore:
4467 AdvanceToken();
4468 continue;
4469 case RangeAfter:
4470 case RangeOverlap:
4471 break;
4472 }
4473 break;
4474 }
4475
4476 // Look at all of the tokens within this range.
4477 while (MoreTokens()) {
4478 const unsigned I = NextToken();
4479 SourceLocation TokLoc = GetTokenLoc(I);
4480 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4481 case RangeBefore:
4482 assert(0 && "Infeasible");
4483 case RangeAfter:
4484 break;
4485 case RangeOverlap:
4486 Cursors[I] = cursor;
4487 AdvanceToken();
4488 continue;
4489 }
4490 break;
4491 }
4492
4493 // Save the preprocessing token index; restore the non-preprocessing
4494 // token index.
4495 PreprocessingTokIdx = TokIdx;
4496 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004497 return CXChildVisit_Recurse;
4498 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004499
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004500 if (cursorRange.isInvalid())
4501 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004502
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004503 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4504
Ted Kremeneka333c662010-05-12 05:29:33 +00004505 // Adjust the annotated range based specific declarations.
4506 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4507 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004508 Decl *D = cxcursor::getCursorDecl(cursor);
4509 // Don't visit synthesized ObjC methods, since they have no syntatic
4510 // representation in the source.
4511 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4512 if (MD->isSynthesized())
4513 return CXChildVisit_Continue;
4514 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004515
4516 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004517 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004518 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4519 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4520 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4521 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4522 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004523 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004524
4525 if (StartLoc.isValid() && L.isValid() &&
4526 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4527 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004528 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004529
Ted Kremenek3f404602010-08-14 01:14:06 +00004530 // If the location of the cursor occurs within a macro instantiation, record
4531 // the spelling location of the cursor in our annotation map. We can then
4532 // paper over the token labelings during a post-processing step to try and
4533 // get cursor mappings for tokens that are the *arguments* of a macro
4534 // instantiation.
4535 if (L.isMacroID()) {
4536 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4537 // Only invalidate the old annotation if it isn't part of a preprocessing
4538 // directive. Here we assume that the default construction of CXCursor
4539 // results in CXCursor.kind being an initialized value (i.e., 0). If
4540 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004541
Ted Kremenek3f404602010-08-14 01:14:06 +00004542 CXCursor &oldC = Annotated[rawEncoding];
4543 if (!clang_isPreprocessing(oldC.kind))
4544 oldC = cursor;
4545 }
4546
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004547 const enum CXCursorKind K = clang_getCursorKind(parent);
4548 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004549 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4550 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004551
4552 while (MoreTokens()) {
4553 const unsigned I = NextToken();
4554 SourceLocation TokLoc = GetTokenLoc(I);
4555 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4556 case RangeBefore:
4557 Cursors[I] = updateC;
4558 AdvanceToken();
4559 continue;
4560 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004561 case RangeOverlap:
4562 break;
4563 }
4564 break;
4565 }
4566
4567 // Visit children to get their cursor information.
4568 const unsigned BeforeChildren = NextToken();
4569 VisitChildren(cursor);
4570 const unsigned AfterChildren = NextToken();
4571
4572 // Adjust 'Last' to the last token within the extent of the cursor.
4573 while (MoreTokens()) {
4574 const unsigned I = NextToken();
4575 SourceLocation TokLoc = GetTokenLoc(I);
4576 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4577 case RangeBefore:
4578 assert(0 && "Infeasible");
4579 case RangeAfter:
4580 break;
4581 case RangeOverlap:
4582 Cursors[I] = updateC;
4583 AdvanceToken();
4584 continue;
4585 }
4586 break;
4587 }
4588 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004589
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004590 // Scan the tokens that are at the beginning of the cursor, but are not
4591 // capture by the child cursors.
4592
4593 // For AST elements within macros, rely on a post-annotate pass to
4594 // to correctly annotate the tokens with cursors. Otherwise we can
4595 // get confusing results of having tokens that map to cursors that really
4596 // are expanded by an instantiation.
4597 if (L.isMacroID())
4598 cursor = clang_getNullCursor();
4599
4600 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4601 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4602 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004603
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004604 Cursors[I] = cursor;
4605 }
4606 // Scan the tokens that are at the end of the cursor, but are not captured
4607 // but the child cursors.
4608 for (unsigned I = AfterChildren; I != Last; ++I)
4609 Cursors[I] = cursor;
4610
4611 TokIdx = Last;
4612 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004613}
4614
Ted Kremenek6db61092010-05-05 00:55:15 +00004615static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4616 CXCursor parent,
4617 CXClientData client_data) {
4618 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4619}
4620
Ted Kremenek6628a612011-03-18 22:51:30 +00004621namespace {
4622 struct clang_annotateTokens_Data {
4623 CXTranslationUnit TU;
4624 ASTUnit *CXXUnit;
4625 CXToken *Tokens;
4626 unsigned NumTokens;
4627 CXCursor *Cursors;
4628 };
4629}
4630
Ted Kremenekab979612010-11-11 08:05:23 +00004631// This gets run a separate thread to avoid stack blowout.
Ted Kremenek6628a612011-03-18 22:51:30 +00004632static void clang_annotateTokensImpl(void *UserData) {
4633 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4634 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4635 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4636 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4637 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4638
4639 // Determine the region of interest, which contains all of the tokens.
4640 SourceRange RegionOfInterest;
4641 RegionOfInterest.setBegin(
4642 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4643 RegionOfInterest.setEnd(
4644 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4645 Tokens[NumTokens-1])));
4646
4647 // A mapping from the source locations found when re-lexing or traversing the
4648 // region of interest to the corresponding cursors.
4649 AnnotateTokensData Annotated;
4650
4651 // Relex the tokens within the source range to look for preprocessing
4652 // directives.
4653 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4654 std::pair<FileID, unsigned> BeginLocInfo
4655 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4656 std::pair<FileID, unsigned> EndLocInfo
4657 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4658
4659 llvm::StringRef Buffer;
4660 bool Invalid = false;
4661 if (BeginLocInfo.first == EndLocInfo.first &&
4662 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4663 !Invalid) {
4664 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4665 CXXUnit->getASTContext().getLangOptions(),
4666 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4667 Buffer.end());
4668 Lex.SetCommentRetentionState(true);
4669
4670 // Lex tokens in raw mode until we hit the end of the range, to avoid
4671 // entering #includes or expanding macros.
4672 while (true) {
4673 Token Tok;
4674 Lex.LexFromRawLexer(Tok);
4675
4676 reprocess:
4677 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4678 // We have found a preprocessing directive. Gobble it up so that we
4679 // don't see it while preprocessing these tokens later, but keep track
4680 // of all of the token locations inside this preprocessing directive so
4681 // that we can annotate them appropriately.
4682 //
4683 // FIXME: Some simple tests here could identify macro definitions and
4684 // #undefs, to provide specific cursor kinds for those.
4685 llvm::SmallVector<SourceLocation, 32> Locations;
4686 do {
4687 Locations.push_back(Tok.getLocation());
4688 Lex.LexFromRawLexer(Tok);
4689 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4690
4691 using namespace cxcursor;
4692 CXCursor Cursor
4693 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4694 Locations.back()),
4695 TU);
4696 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4697 Annotated[Locations[I].getRawEncoding()] = Cursor;
4698 }
4699
4700 if (Tok.isAtStartOfLine())
4701 goto reprocess;
4702
4703 continue;
4704 }
4705
4706 if (Tok.is(tok::eof))
4707 break;
4708 }
4709 }
4710
4711 // Annotate all of the source locations in the region of interest that map to
4712 // a specific cursor.
4713 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4714 TU, RegionOfInterest);
4715
4716 // FIXME: We use a ridiculous stack size here because the data-recursion
4717 // algorithm uses a large stack frame than the non-data recursive version,
4718 // and AnnotationTokensWorker currently transforms the data-recursion
4719 // algorithm back into a traditional recursion by explicitly calling
4720 // VisitChildren(). We will need to remove this explicit recursive call.
4721 W.AnnotateTokens();
4722
4723 // If we ran into any entities that involve context-sensitive keywords,
4724 // take another pass through the tokens to mark them as such.
4725 if (W.hasContextSensitiveKeywords()) {
4726 for (unsigned I = 0; I != NumTokens; ++I) {
4727 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4728 continue;
4729
4730 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4731 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4732 if (ObjCPropertyDecl *Property
4733 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4734 if (Property->getPropertyAttributesAsWritten() != 0 &&
4735 llvm::StringSwitch<bool>(II->getName())
4736 .Case("readonly", true)
4737 .Case("assign", true)
4738 .Case("readwrite", true)
4739 .Case("retain", true)
4740 .Case("copy", true)
4741 .Case("nonatomic", true)
4742 .Case("atomic", true)
4743 .Case("getter", true)
4744 .Case("setter", true)
4745 .Default(false))
4746 Tokens[I].int_data[0] = CXToken_Keyword;
4747 }
4748 continue;
4749 }
4750
4751 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4752 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4753 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4754 if (llvm::StringSwitch<bool>(II->getName())
4755 .Case("in", true)
4756 .Case("out", true)
4757 .Case("inout", true)
4758 .Case("oneway", true)
4759 .Case("bycopy", true)
4760 .Case("byref", true)
4761 .Default(false))
4762 Tokens[I].int_data[0] = CXToken_Keyword;
4763 continue;
4764 }
4765
4766 if (Cursors[I].kind == CXCursor_CXXMethod) {
4767 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4768 if (CXXMethodDecl *Method
4769 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4770 if ((Method->hasAttr<FinalAttr>() ||
4771 Method->hasAttr<OverrideAttr>()) &&
4772 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4773 llvm::StringSwitch<bool>(II->getName())
4774 .Case("final", true)
4775 .Case("override", true)
4776 .Default(false))
4777 Tokens[I].int_data[0] = CXToken_Keyword;
4778 }
4779 continue;
4780 }
4781
4782 if (Cursors[I].kind == CXCursor_ClassDecl ||
4783 Cursors[I].kind == CXCursor_StructDecl ||
4784 Cursors[I].kind == CXCursor_ClassTemplate) {
4785 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4786 if (II->getName() == "final") {
4787 // We have to be careful with 'final', since it could be the name
4788 // of a member class rather than the context-sensitive keyword.
4789 // So, check whether the cursor associated with this
4790 Decl *D = getCursorDecl(Cursors[I]);
4791 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4792 if ((Record->hasAttr<FinalAttr>()) &&
4793 Record->getIdentifier() != II)
4794 Tokens[I].int_data[0] = CXToken_Keyword;
4795 } else if (ClassTemplateDecl *ClassTemplate
4796 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4797 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4798 if ((Record->hasAttr<FinalAttr>()) &&
4799 Record->getIdentifier() != II)
4800 Tokens[I].int_data[0] = CXToken_Keyword;
4801 }
4802 }
4803 continue;
4804 }
4805 }
4806 }
Ted Kremenekab979612010-11-11 08:05:23 +00004807}
4808
Ted Kremenek6db61092010-05-05 00:55:15 +00004809extern "C" {
4810
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004811void clang_annotateTokens(CXTranslationUnit TU,
4812 CXToken *Tokens, unsigned NumTokens,
4813 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004814
4815 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004816 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004817
Douglas Gregor4419b672010-10-21 06:10:04 +00004818 // Any token we don't specifically annotate will have a NULL cursor.
4819 CXCursor C = clang_getNullCursor();
4820 for (unsigned I = 0; I != NumTokens; ++I)
4821 Cursors[I] = C;
4822
Ted Kremeneka60ed472010-11-16 08:15:36 +00004823 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004824 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004825 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004826
Douglas Gregorbdf60622010-03-05 21:16:25 +00004827 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek6628a612011-03-18 22:51:30 +00004828
4829 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekab979612010-11-11 08:05:23 +00004830 llvm::CrashRecoveryContext CRC;
Ted Kremenek6628a612011-03-18 22:51:30 +00004831 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004832 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004833 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4834 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004835}
Ted Kremenek6628a612011-03-18 22:51:30 +00004836
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004837} // end: extern "C"
4838
4839//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004840// Operations for querying linkage of a cursor.
4841//===----------------------------------------------------------------------===//
4842
4843extern "C" {
4844CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004845 if (!clang_isDeclaration(cursor.kind))
4846 return CXLinkage_Invalid;
4847
Ted Kremenek16b42592010-03-03 06:36:57 +00004848 Decl *D = cxcursor::getCursorDecl(cursor);
4849 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4850 switch (ND->getLinkage()) {
4851 case NoLinkage: return CXLinkage_NoLinkage;
4852 case InternalLinkage: return CXLinkage_Internal;
4853 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4854 case ExternalLinkage: return CXLinkage_External;
4855 };
4856
4857 return CXLinkage_Invalid;
4858}
4859} // end: extern "C"
4860
4861//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004862// Operations for querying language of a cursor.
4863//===----------------------------------------------------------------------===//
4864
4865static CXLanguageKind getDeclLanguage(const Decl *D) {
4866 switch (D->getKind()) {
4867 default:
4868 break;
4869 case Decl::ImplicitParam:
4870 case Decl::ObjCAtDefsField:
4871 case Decl::ObjCCategory:
4872 case Decl::ObjCCategoryImpl:
4873 case Decl::ObjCClass:
4874 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004875 case Decl::ObjCForwardProtocol:
4876 case Decl::ObjCImplementation:
4877 case Decl::ObjCInterface:
4878 case Decl::ObjCIvar:
4879 case Decl::ObjCMethod:
4880 case Decl::ObjCProperty:
4881 case Decl::ObjCPropertyImpl:
4882 case Decl::ObjCProtocol:
4883 return CXLanguage_ObjC;
4884 case Decl::CXXConstructor:
4885 case Decl::CXXConversion:
4886 case Decl::CXXDestructor:
4887 case Decl::CXXMethod:
4888 case Decl::CXXRecord:
4889 case Decl::ClassTemplate:
4890 case Decl::ClassTemplatePartialSpecialization:
4891 case Decl::ClassTemplateSpecialization:
4892 case Decl::Friend:
4893 case Decl::FriendTemplate:
4894 case Decl::FunctionTemplate:
4895 case Decl::LinkageSpec:
4896 case Decl::Namespace:
4897 case Decl::NamespaceAlias:
4898 case Decl::NonTypeTemplateParm:
4899 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004900 case Decl::TemplateTemplateParm:
4901 case Decl::TemplateTypeParm:
4902 case Decl::UnresolvedUsingTypename:
4903 case Decl::UnresolvedUsingValue:
4904 case Decl::Using:
4905 case Decl::UsingDirective:
4906 case Decl::UsingShadow:
4907 return CXLanguage_CPlusPlus;
4908 }
4909
4910 return CXLanguage_C;
4911}
4912
4913extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004914
4915enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4916 if (clang_isDeclaration(cursor.kind))
4917 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004918 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregor58ddb602010-08-23 23:00:57 +00004919 return CXAvailability_Available;
4920
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004921 switch (D->getAvailability()) {
4922 case AR_Available:
4923 case AR_NotYetIntroduced:
4924 return CXAvailability_Available;
4925
4926 case AR_Deprecated:
Douglas Gregor58ddb602010-08-23 23:00:57 +00004927 return CXAvailability_Deprecated;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004928
4929 case AR_Unavailable:
4930 return CXAvailability_NotAvailable;
4931 }
Douglas Gregor58ddb602010-08-23 23:00:57 +00004932 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004933
Douglas Gregor58ddb602010-08-23 23:00:57 +00004934 return CXAvailability_Available;
4935}
4936
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004937CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4938 if (clang_isDeclaration(cursor.kind))
4939 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4940
4941 return CXLanguage_Invalid;
4942}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004943
4944 /// \brief If the given cursor is the "templated" declaration
4945 /// descibing a class or function template, return the class or
4946 /// function template.
4947static Decl *maybeGetTemplateCursor(Decl *D) {
4948 if (!D)
4949 return 0;
4950
4951 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4952 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4953 return FunTmpl;
4954
4955 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4956 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4957 return ClassTmpl;
4958
4959 return D;
4960}
4961
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004962CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4963 if (clang_isDeclaration(cursor.kind)) {
4964 if (Decl *D = getCursorDecl(cursor)) {
4965 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004966 if (!DC)
4967 return clang_getNullCursor();
4968
4969 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4970 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004971 }
4972 }
4973
4974 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4975 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004976 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004977 }
4978
4979 return clang_getNullCursor();
4980}
4981
4982CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4983 if (clang_isDeclaration(cursor.kind)) {
4984 if (Decl *D = getCursorDecl(cursor)) {
4985 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004986 if (!DC)
4987 return clang_getNullCursor();
4988
4989 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4990 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004991 }
4992 }
4993
4994 // FIXME: Note that we can't easily compute the lexical context of a
4995 // statement or expression, so we return nothing.
4996 return clang_getNullCursor();
4997}
4998
Douglas Gregor9f592342010-10-01 20:25:15 +00004999static void CollectOverriddenMethods(DeclContext *Ctx,
5000 ObjCMethodDecl *Method,
5001 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5002 if (!Ctx)
5003 return;
5004
5005 // If we have a class or category implementation, jump straight to the
5006 // interface.
5007 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5008 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5009
5010 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5011 if (!Container)
5012 return;
5013
5014 // Check whether we have a matching method at this level.
5015 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5016 Method->isInstanceMethod()))
5017 if (Method != Overridden) {
5018 // We found an override at this level; there is no need to look
5019 // into other protocols or categories.
5020 Methods.push_back(Overridden);
5021 return;
5022 }
5023
5024 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5025 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5026 PEnd = Protocol->protocol_end();
5027 P != PEnd; ++P)
5028 CollectOverriddenMethods(*P, Method, Methods);
5029 }
5030
5031 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5032 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5033 PEnd = Category->protocol_end();
5034 P != PEnd; ++P)
5035 CollectOverriddenMethods(*P, Method, Methods);
5036 }
5037
5038 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5039 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5040 PEnd = Interface->protocol_end();
5041 P != PEnd; ++P)
5042 CollectOverriddenMethods(*P, Method, Methods);
5043
5044 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5045 Category; Category = Category->getNextClassCategory())
5046 CollectOverriddenMethods(Category, Method, Methods);
5047
5048 // We only look into the superclass if we haven't found anything yet.
5049 if (Methods.empty())
5050 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5051 return CollectOverriddenMethods(Super, Method, Methods);
5052 }
5053}
5054
5055void clang_getOverriddenCursors(CXCursor cursor,
5056 CXCursor **overridden,
5057 unsigned *num_overridden) {
5058 if (overridden)
5059 *overridden = 0;
5060 if (num_overridden)
5061 *num_overridden = 0;
5062 if (!overridden || !num_overridden)
5063 return;
5064
5065 if (!clang_isDeclaration(cursor.kind))
5066 return;
5067
5068 Decl *D = getCursorDecl(cursor);
5069 if (!D)
5070 return;
5071
5072 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00005073 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00005074 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5075 *num_overridden = CXXMethod->size_overridden_methods();
5076 if (!*num_overridden)
5077 return;
5078
5079 *overridden = new CXCursor [*num_overridden];
5080 unsigned I = 0;
5081 for (CXXMethodDecl::method_iterator
5082 M = CXXMethod->begin_overridden_methods(),
5083 MEnd = CXXMethod->end_overridden_methods();
5084 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005085 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005086 return;
5087 }
5088
5089 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5090 if (!Method)
5091 return;
5092
5093 // Handle Objective-C methods.
5094 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5095 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5096
5097 if (Methods.empty())
5098 return;
5099
5100 *num_overridden = Methods.size();
5101 *overridden = new CXCursor [Methods.size()];
5102 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005103 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005104}
5105
5106void clang_disposeOverriddenCursors(CXCursor *overridden) {
5107 delete [] overridden;
5108}
5109
Douglas Gregorecdcb882010-10-20 22:00:55 +00005110CXFile clang_getIncludedFile(CXCursor cursor) {
5111 if (cursor.kind != CXCursor_InclusionDirective)
5112 return 0;
5113
5114 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5115 return (void *)ID->getFile();
5116}
5117
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005118} // end: extern "C"
5119
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005120
5121//===----------------------------------------------------------------------===//
5122// C++ AST instrospection.
5123//===----------------------------------------------------------------------===//
5124
5125extern "C" {
5126unsigned clang_CXXMethod_isStatic(CXCursor C) {
5127 if (!clang_isDeclaration(C.kind))
5128 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005129
5130 CXXMethodDecl *Method = 0;
5131 Decl *D = cxcursor::getCursorDecl(C);
5132 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5133 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5134 else
5135 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5136 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005137}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005138
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005139} // end: extern "C"
5140
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005141//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005142// Attribute introspection.
5143//===----------------------------------------------------------------------===//
5144
5145extern "C" {
5146CXType clang_getIBOutletCollectionType(CXCursor C) {
5147 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005148 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005149
5150 IBOutletCollectionAttr *A =
5151 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5152
Douglas Gregor841b2382011-03-06 18:55:32 +00005153 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005154}
5155} // end: extern "C"
5156
5157//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005158// Misc. utility functions.
5159//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005160
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005161/// Default to using an 8 MB stack size on "safety" threads.
5162static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005163
5164namespace clang {
5165
5166bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005167 void (*Fn)(void*), void *UserData,
5168 unsigned Size) {
5169 if (!Size)
5170 Size = GetSafetyThreadStackSize();
5171 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005172 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5173 return CRC.RunSafely(Fn, UserData);
5174}
5175
5176unsigned GetSafetyThreadStackSize() {
5177 return SafetyStackThreadSize;
5178}
5179
5180void SetSafetyThreadStackSize(unsigned Value) {
5181 SafetyStackThreadSize = Value;
5182}
5183
5184}
5185
Ted Kremenek04bb7162010-01-22 22:44:15 +00005186extern "C" {
5187
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005188CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005189 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005190}
5191
5192} // end: extern "C"