blob: b12e7fe41e6109c5e182f16301771e716ccc7bd4 [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:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001396 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001397
Ted Kremenekc4174cc2010-02-18 18:52:18 +00001398 case BuiltinType::ObjCId:
1399 VisitType = Context.getObjCIdType();
1400 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001401
1402 case BuiltinType::ObjCClass:
1403 VisitType = Context.getObjCClassType();
1404 break;
1405
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001406 case BuiltinType::ObjCSel:
1407 VisitType = Context.getObjCSelType();
1408 break;
1409 }
1410
1411 if (!VisitType.isNull()) {
1412 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001413 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001414 TU));
1415 }
1416
1417 return false;
1418}
1419
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001420bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1421 return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
1422}
1423
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001424bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1425 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1426}
1427
1428bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1429 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1430}
1431
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001432bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001433 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001434 // no context information with which we can match up the depth/index in the
1435 // type to the appropriate
1436 return false;
1437}
1438
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001439bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1440 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1441 return true;
1442
John McCallc12c5bb2010-05-15 11:32:37 +00001443 return false;
1444}
1445
1446bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1447 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1448 return true;
1449
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001450 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1451 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1452 TU)))
1453 return true;
1454 }
1455
1456 return false;
1457}
1458
1459bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCallc12c5bb2010-05-15 11:32:37 +00001460 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001461}
1462
Abramo Bagnara075f8f12010-12-10 16:29:40 +00001463bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1464 return Visit(TL.getInnerLoc());
1465}
1466
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001467bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1468 return Visit(TL.getPointeeLoc());
1469}
1470
1471bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1472 return Visit(TL.getPointeeLoc());
1473}
1474
1475bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1476 return Visit(TL.getPointeeLoc());
1477}
1478
1479bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001480 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001481}
1482
1483bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001484 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001485}
1486
Douglas Gregor01829d32010-08-31 14:41:23 +00001487bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1488 bool SkipResultType) {
1489 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001490 return true;
1491
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001492 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek5dbacb42010-04-07 00:27:13 +00001493 if (Decl *D = TL.getArg(I))
1494 if (Visit(MakeCXCursor(D, TU)))
1495 return true;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001496
1497 return false;
1498}
1499
1500bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1501 if (Visit(TL.getElementLoc()))
1502 return true;
1503
1504 if (Expr *Size = TL.getSizeExpr())
1505 return Visit(MakeCXCursor(Size, StmtParent, TU));
1506
1507 return false;
1508}
1509
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001510bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1511 TemplateSpecializationTypeLoc TL) {
Douglas Gregor0b36e612010-08-31 20:37:03 +00001512 // Visit the template name.
1513 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1514 TL.getTemplateNameLoc()))
1515 return true;
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001516
1517 // Visit the template arguments.
1518 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1519 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1520 return true;
1521
1522 return false;
1523}
1524
Douglas Gregor2332c112010-01-21 20:48:56 +00001525bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1526 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1527}
1528
1529bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1530 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1531 return Visit(TSInfo->getTypeLoc());
1532
1533 return false;
1534}
1535
Douglas Gregor2494dd02011-03-01 01:34:45 +00001536bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1537 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1538 return true;
1539
1540 return false;
1541}
1542
Douglas Gregor94fdffa2011-03-01 20:11:18 +00001543bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1544 DependentTemplateSpecializationTypeLoc TL) {
1545 // Visit the nested-name-specifier, if there is one.
1546 if (TL.getQualifierLoc() &&
1547 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1548 return true;
1549
1550 // Visit the template arguments.
1551 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1552 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1553 return true;
1554
1555 return false;
1556}
1557
Douglas Gregor9e876872011-03-01 18:12:44 +00001558bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1559 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1560 return true;
1561
1562 return Visit(TL.getNamedTypeLoc());
1563}
1564
Douglas Gregor7536dd52010-12-20 02:24:11 +00001565bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1566 return Visit(TL.getPatternLoc());
1567}
1568
Ted Kremenek3064ef92010-08-27 21:34:58 +00001569bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001570 // Visit the nested-name-specifier, if present.
1571 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1572 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1573 return true;
1574
Ted Kremenek3064ef92010-08-27 21:34:58 +00001575 if (D->isDefinition()) {
1576 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1577 E = D->bases_end(); I != E; ++I) {
1578 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1579 return true;
1580 }
1581 }
1582
1583 return VisitTagDecl(D);
1584}
1585
Ted Kremenek09dfa372010-02-18 05:46:33 +00001586bool CursorVisitor::VisitAttributes(Decl *D) {
Sean Huntcf807c42010-08-18 23:23:40 +00001587 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1588 i != e; ++i)
1589 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek09dfa372010-02-18 05:46:33 +00001590 return true;
1591
1592 return false;
1593}
1594
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001595//===----------------------------------------------------------------------===//
1596// Data-recursive visitor methods.
1597//===----------------------------------------------------------------------===//
1598
Ted Kremenek28a71942010-11-13 00:36:47 +00001599namespace {
Ted Kremenek035dc412010-11-13 00:36:50 +00001600#define DEF_JOB(NAME, DATA, KIND)\
1601class NAME : public VisitorJob {\
1602public:\
1603 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1604 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenekf64d8032010-11-18 00:02:32 +00001605 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek035dc412010-11-13 00:36:50 +00001606};
1607
1608DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1609DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001610DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001611DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek60608ec2010-11-17 00:50:47 +00001612DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1613 ExplicitTemplateArgsVisitKind)
Douglas Gregor94d96292011-01-19 20:34:17 +00001614DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001615#undef DEF_JOB
1616
1617class DeclVisit : public VisitorJob {
1618public:
1619 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1620 VisitorJob(parent, VisitorJob::DeclVisitKind,
1621 d, isFirst ? (void*) 1 : (void*) 0) {}
1622 static bool classof(const VisitorJob *VJ) {
Ted Kremenek82f3c502010-11-15 22:23:26 +00001623 return VJ->getKind() == DeclVisitKind;
Ted Kremenek035dc412010-11-13 00:36:50 +00001624 }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001625 Decl *get() const { return static_cast<Decl*>(data[0]); }
1626 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek035dc412010-11-13 00:36:50 +00001627};
Ted Kremenek035dc412010-11-13 00:36:50 +00001628class TypeLocVisit : public VisitorJob {
1629public:
1630 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1631 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1632 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1633
1634 static bool classof(const VisitorJob *VJ) {
1635 return VJ->getKind() == TypeLocVisitKind;
1636 }
1637
Ted Kremenek82f3c502010-11-15 22:23:26 +00001638 TypeLoc get() const {
Ted Kremenekf64d8032010-11-18 00:02:32 +00001639 QualType T = QualType::getFromOpaquePtr(data[0]);
1640 return TypeLoc(T, data[1]);
Ted Kremenek035dc412010-11-13 00:36:50 +00001641 }
1642};
1643
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001644class LabelRefVisit : public VisitorJob {
1645public:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001646 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1647 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001648 labelLoc.getPtrEncoding()) {}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001649
1650 static bool classof(const VisitorJob *VJ) {
1651 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1652 }
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001653 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001654 SourceLocation getLoc() const {
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001655 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001656};
1657class NestedNameSpecifierVisit : public VisitorJob {
1658public:
1659 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1660 CXCursor parent)
1661 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001662 NS, R.getBegin().getPtrEncoding(),
1663 R.getEnd().getPtrEncoding()) {}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001664 static bool classof(const VisitorJob *VJ) {
1665 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1666 }
1667 NestedNameSpecifier *get() const {
1668 return static_cast<NestedNameSpecifier*>(data[0]);
1669 }
1670 SourceRange getSourceRange() const {
1671 SourceLocation A =
1672 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1673 SourceLocation B =
1674 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1675 return SourceRange(A, B);
1676 }
1677};
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001678
1679class NestedNameSpecifierLocVisit : public VisitorJob {
1680public:
1681 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1682 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1683 Qualifier.getNestedNameSpecifier(),
1684 Qualifier.getOpaqueData()) { }
1685
1686 static bool classof(const VisitorJob *VJ) {
1687 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1688 }
1689
1690 NestedNameSpecifierLoc get() const {
1691 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1692 data[1]);
1693 }
1694};
1695
Ted Kremenekf64d8032010-11-18 00:02:32 +00001696class DeclarationNameInfoVisit : public VisitorJob {
1697public:
1698 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1699 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1700 static bool classof(const VisitorJob *VJ) {
1701 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1702 }
1703 DeclarationNameInfo get() const {
1704 Stmt *S = static_cast<Stmt*>(data[0]);
1705 switch (S->getStmtClass()) {
1706 default:
1707 llvm_unreachable("Unhandled Stmt");
1708 case Stmt::CXXDependentScopeMemberExprClass:
1709 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1710 case Stmt::DependentScopeDeclRefExprClass:
1711 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1712 }
1713 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001714};
Ted Kremenekcdba6592010-11-18 00:42:18 +00001715class MemberRefVisit : public VisitorJob {
1716public:
1717 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1718 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001719 L.getPtrEncoding()) {}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001720 static bool classof(const VisitorJob *VJ) {
1721 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1722 }
1723 FieldDecl *get() const {
1724 return static_cast<FieldDecl*>(data[0]);
1725 }
1726 SourceLocation getLoc() const {
1727 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1728 }
1729};
Ted Kremenek28a71942010-11-13 00:36:47 +00001730class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1731 VisitorWorkList &WL;
1732 CXCursor Parent;
1733public:
1734 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1735 : WL(wl), Parent(parent) {}
1736
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001737 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001738 void VisitBlockExpr(BlockExpr *B);
Ted Kremenek28a71942010-11-13 00:36:47 +00001739 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenek083c7e22010-11-13 05:38:03 +00001740 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001741 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001742 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001743 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001744 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001745 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001746 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001747 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001748 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek55b933a2010-11-17 00:50:36 +00001749 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001750 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001751 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek035dc412010-11-13 00:36:50 +00001752 void VisitDeclStmt(DeclStmt *S);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001753 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001754 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001755 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1756 void VisitForStmt(ForStmt *FS);
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001757 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenek28a71942010-11-13 00:36:47 +00001758 void VisitIfStmt(IfStmt *If);
1759 void VisitInitListExpr(InitListExpr *IE);
1760 void VisitMemberExpr(MemberExpr *M);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001761 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001762 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001763 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1764 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00001765 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001766 void VisitStmt(Stmt *S);
1767 void VisitSwitchStmt(SwitchStmt *S);
1768 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek2939b6f2010-11-17 00:50:50 +00001769 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet6ad6f282010-12-07 00:08:36 +00001770 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001771 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenek9d3bf792010-11-17 00:50:43 +00001772 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor94d96292011-01-19 20:34:17 +00001773 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregoree8aff02011-01-04 17:33:58 +00001774
Ted Kremenek28a71942010-11-13 00:36:47 +00001775private:
Ted Kremenekf64d8032010-11-18 00:02:32 +00001776 void AddDeclarationNameInfo(Stmt *S);
1777 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001778 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek60608ec2010-11-17 00:50:47 +00001779 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001780 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenek28a71942010-11-13 00:36:47 +00001781 void AddStmt(Stmt *S);
Ted Kremenek035dc412010-11-13 00:36:50 +00001782 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenek28a71942010-11-13 00:36:47 +00001783 void AddTypeLoc(TypeSourceInfo *TI);
1784 void EnqueueChildren(Stmt *S);
1785};
1786} // end anonyous namespace
1787
Ted Kremenekf64d8032010-11-18 00:02:32 +00001788void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1789 // 'S' should always be non-null, since it comes from the
1790 // statement we are visiting.
1791 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1792}
1793void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1794 SourceRange R) {
1795 if (N)
1796 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1797}
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001798
1799void
1800EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1801 if (Qualifier)
1802 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1803}
1804
Ted Kremenek28a71942010-11-13 00:36:47 +00001805void EnqueueVisitor::AddStmt(Stmt *S) {
1806 if (S)
1807 WL.push_back(StmtVisit(S, Parent));
1808}
Ted Kremenek035dc412010-11-13 00:36:50 +00001809void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001810 if (D)
Ted Kremenek035dc412010-11-13 00:36:50 +00001811 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenek28a71942010-11-13 00:36:47 +00001812}
Ted Kremenek60608ec2010-11-17 00:50:47 +00001813void EnqueueVisitor::
1814 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1815 if (A)
1816 WL.push_back(ExplicitTemplateArgsVisit(
1817 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1818}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001819void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1820 if (D)
1821 WL.push_back(MemberRefVisit(D, L, Parent));
1822}
Ted Kremenek28a71942010-11-13 00:36:47 +00001823void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1824 if (TI)
1825 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1826 }
1827void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremeneka6b70432010-11-12 21:34:09 +00001828 unsigned size = WL.size();
John McCall7502c1d2011-02-13 04:07:26 +00001829 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001830 AddStmt(*Child);
Ted Kremeneka6b70432010-11-12 21:34:09 +00001831 }
1832 if (size == WL.size())
1833 return;
1834 // Now reverse the entries we just added. This will match the DFS
1835 // ordering performed by the worklist.
1836 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1837 std::reverse(I, E);
1838}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001839void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1840 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1841}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001842void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1843 AddDecl(B->getBlockDecl());
1844}
Ted Kremenek28a71942010-11-13 00:36:47 +00001845void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1846 EnqueueChildren(E);
1847 AddTypeLoc(E->getTypeSourceInfo());
1848}
Ted Kremenek083c7e22010-11-13 05:38:03 +00001849void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1850 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1851 E = S->body_rend(); I != E; ++I) {
1852 AddStmt(*I);
1853 }
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001854}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001855void EnqueueVisitor::
1856VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1857 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1858 AddDeclarationNameInfo(E);
Douglas Gregor7c3179c2011-02-28 18:50:33 +00001859 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1860 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001861 if (!E->isImplicitAccess())
1862 AddStmt(E->getBase());
1863}
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001864void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1865 // Enqueue the initializer or constructor arguments.
1866 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1867 AddStmt(E->getConstructorArg(I-1));
1868 // Enqueue the array size, if any.
1869 AddStmt(E->getArraySize());
1870 // Enqueue the allocated type.
1871 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1872 // Enqueue the placement arguments.
1873 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1874 AddStmt(E->getPlacementArg(I-1));
1875}
Ted Kremenek28a71942010-11-13 00:36:47 +00001876void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenek8b8d8c92010-11-13 05:55:56 +00001877 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1878 AddStmt(CE->getArg(I-1));
Ted Kremenek28a71942010-11-13 00:36:47 +00001879 AddStmt(CE->getCallee());
1880 AddStmt(CE->getArg(0));
1881}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001882void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1883 // Visit the name of the type being destroyed.
1884 AddTypeLoc(E->getDestroyedTypeInfo());
1885 // Visit the scope type that looks disturbingly like the nested-name-specifier
1886 // but isn't.
1887 AddTypeLoc(E->getScopeTypeInfo());
1888 // Visit the nested-name-specifier.
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001889 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1890 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001891 // Visit base expression.
1892 AddStmt(E->getBase());
1893}
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001894void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1895 AddTypeLoc(E->getTypeSourceInfo());
1896}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001897void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1898 EnqueueChildren(E);
1899 AddTypeLoc(E->getTypeSourceInfo());
1900}
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001901void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1902 EnqueueChildren(E);
1903 if (E->isTypeOperand())
1904 AddTypeLoc(E->getTypeOperandSourceInfo());
1905}
Ted Kremenek55b933a2010-11-17 00:50:36 +00001906
1907void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1908 *E) {
1909 EnqueueChildren(E);
1910 AddTypeLoc(E->getTypeSourceInfo());
1911}
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001912void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1913 EnqueueChildren(E);
1914 if (E->isTypeOperand())
1915 AddTypeLoc(E->getTypeOperandSourceInfo());
1916}
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001917void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00001918 if (DR->hasExplicitTemplateArgs()) {
1919 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1920 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001921 WL.push_back(DeclRefExprParts(DR, Parent));
1922}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001923void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1924 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1925 AddDeclarationNameInfo(E);
Douglas Gregor00cf3cc2011-02-25 20:49:16 +00001926 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenekf64d8032010-11-18 00:02:32 +00001927}
Ted Kremenek035dc412010-11-13 00:36:50 +00001928void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1929 unsigned size = WL.size();
1930 bool isFirst = true;
1931 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1932 D != DEnd; ++D) {
1933 AddDecl(*D, isFirst);
1934 isFirst = false;
1935 }
1936 if (size == WL.size())
1937 return;
1938 // Now reverse the entries we just added. This will match the DFS
1939 // ordering performed by the worklist.
1940 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1941 std::reverse(I, E);
1942}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001943void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1944 AddStmt(E->getInit());
1945 typedef DesignatedInitExpr::Designator Designator;
1946 for (DesignatedInitExpr::reverse_designators_iterator
1947 D = E->designators_rbegin(), DEnd = E->designators_rend();
1948 D != DEnd; ++D) {
1949 if (D->isFieldDesignator()) {
1950 if (FieldDecl *Field = D->getField())
1951 AddMemberRef(Field, D->getFieldLoc());
1952 continue;
1953 }
1954 if (D->isArrayDesignator()) {
1955 AddStmt(E->getArrayIndex(*D));
1956 continue;
1957 }
1958 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1959 AddStmt(E->getArrayRangeEnd(*D));
1960 AddStmt(E->getArrayRangeStart(*D));
1961 }
1962}
Ted Kremenek28a71942010-11-13 00:36:47 +00001963void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1964 EnqueueChildren(E);
1965 AddTypeLoc(E->getTypeInfoAsWritten());
1966}
1967void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1968 AddStmt(FS->getBody());
1969 AddStmt(FS->getInc());
1970 AddStmt(FS->getCond());
1971 AddDecl(FS->getConditionVariable());
1972 AddStmt(FS->getInit());
1973}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001974void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1975 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1976}
Ted Kremenek28a71942010-11-13 00:36:47 +00001977void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
1978 AddStmt(If->getElse());
1979 AddStmt(If->getThen());
1980 AddStmt(If->getCond());
1981 AddDecl(If->getConditionVariable());
1982}
1983void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
1984 // We care about the syntactic form of the initializer list, only.
1985 if (InitListExpr *Syntactic = IE->getSyntacticForm())
1986 IE = Syntactic;
1987 EnqueueChildren(IE);
1988}
1989void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor89629a72010-11-17 17:15:08 +00001990 WL.push_back(MemberExprParts(M, Parent));
1991
1992 // If the base of the member access expression is an implicit 'this', don't
1993 // visit it.
1994 // FIXME: If we ever want to show these implicit accesses, this will be
1995 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor75e85042011-03-02 21:06:53 +00001996 if (!M->isImplicitAccess())
1997 AddStmt(M->getBase());
Ted Kremenek28a71942010-11-13 00:36:47 +00001998}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001999void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2000 AddTypeLoc(E->getEncodedTypeSourceInfo());
2001}
Ted Kremenek28a71942010-11-13 00:36:47 +00002002void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2003 EnqueueChildren(M);
2004 AddTypeLoc(M->getClassReceiverTypeInfo());
2005}
Ted Kremenekcdba6592010-11-18 00:42:18 +00002006void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2007 // Visit the components of the offsetof expression.
2008 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2009 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2010 const OffsetOfNode &Node = E->getComponent(I-1);
2011 switch (Node.getKind()) {
2012 case OffsetOfNode::Array:
2013 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2014 break;
2015 case OffsetOfNode::Field:
Abramo Bagnara06dec892011-03-12 09:45:03 +00002016 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenekcdba6592010-11-18 00:42:18 +00002017 break;
2018 case OffsetOfNode::Identifier:
2019 case OffsetOfNode::Base:
2020 continue;
2021 }
2022 }
2023 // Visit the type into which we're computing the offset.
2024 AddTypeLoc(E->getTypeSourceInfo());
2025}
Ted Kremenek28a71942010-11-13 00:36:47 +00002026void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00002027 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenek60458782010-11-12 21:34:16 +00002028 WL.push_back(OverloadExprParts(E, Parent));
2029}
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00002030void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2031 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00002032 EnqueueChildren(E);
2033 if (E->isArgumentType())
2034 AddTypeLoc(E->getArgumentTypeInfo());
2035}
Ted Kremenek28a71942010-11-13 00:36:47 +00002036void EnqueueVisitor::VisitStmt(Stmt *S) {
2037 EnqueueChildren(S);
2038}
2039void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2040 AddStmt(S->getBody());
2041 AddStmt(S->getCond());
2042 AddDecl(S->getConditionVariable());
2043}
Ted Kremenekfafa75a2010-11-17 00:50:39 +00002044
Ted Kremenek28a71942010-11-13 00:36:47 +00002045void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2046 AddStmt(W->getBody());
2047 AddStmt(W->getCond());
2048 AddDecl(W->getConditionVariable());
2049}
Ted Kremenek2939b6f2010-11-17 00:50:50 +00002050void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2051 AddTypeLoc(E->getQueriedTypeSourceInfo());
2052}
Francois Pichet6ad6f282010-12-07 00:08:36 +00002053
2054void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet6ad6f282010-12-07 00:08:36 +00002055 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichet0a03a3f2010-12-08 09:11:05 +00002056 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet6ad6f282010-12-07 00:08:36 +00002057}
2058
Ted Kremenek28a71942010-11-13 00:36:47 +00002059void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2060 VisitOverloadExpr(U);
2061 if (!U->isImplicitAccess())
2062 AddStmt(U->getBase());
2063}
Ted Kremenek9d3bf792010-11-17 00:50:43 +00002064void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2065 AddStmt(E->getSubExpr());
2066 AddTypeLoc(E->getWrittenTypeInfo());
2067}
Douglas Gregor94d96292011-01-19 20:34:17 +00002068void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2069 WL.push_back(SizeOfPackExprParts(E, Parent));
2070}
Ted Kremenek60458782010-11-12 21:34:16 +00002071
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002072void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenek28a71942010-11-13 00:36:47 +00002073 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002074}
2075
2076bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2077 if (RegionOfInterest.isValid()) {
2078 SourceRange Range = getRawCursorExtent(C);
2079 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2080 return false;
2081 }
2082 return true;
2083}
2084
2085bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2086 while (!WL.empty()) {
2087 // Dequeue the worklist item.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002088 VisitorJob LI = WL.back();
2089 WL.pop_back();
2090
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002091 // Set the Parent field, then back to its old value once we're done.
2092 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2093
2094 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00002095 case VisitorJob::DeclVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002096 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenekf1107452010-11-12 18:26:56 +00002097 if (!D)
2098 continue;
2099
2100 // For now, perform default visitation for Decls.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002101 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenekf1107452010-11-12 18:26:56 +00002102 return true;
2103
2104 continue;
2105 }
Ted Kremenek60608ec2010-11-17 00:50:47 +00002106 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2107 const ExplicitTemplateArgumentList *ArgList =
2108 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2109 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2110 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2111 Arg != ArgEnd; ++Arg) {
2112 if (VisitTemplateArgumentLoc(*Arg))
2113 return true;
2114 }
2115 continue;
2116 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002117 case VisitorJob::TypeLocVisitKind: {
2118 // Perform default visitation for TypeLocs.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002119 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002120 return true;
2121 continue;
2122 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002123 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002124 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremeneke7455012011-02-23 04:54:51 +00002125 if (LabelStmt *stmt = LS->getStmt()) {
2126 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2127 TU))) {
2128 return true;
2129 }
2130 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002131 continue;
2132 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002133
Ted Kremenekf64d8032010-11-18 00:02:32 +00002134 case VisitorJob::NestedNameSpecifierVisitKind: {
2135 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2136 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2137 return true;
2138 continue;
2139 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002140
2141 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2142 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2143 if (VisitNestedNameSpecifierLoc(V->get()))
2144 return true;
2145 continue;
2146 }
2147
Ted Kremenekf64d8032010-11-18 00:02:32 +00002148 case VisitorJob::DeclarationNameInfoVisitKind: {
2149 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2150 ->get()))
2151 return true;
2152 continue;
2153 }
Ted Kremenekcdba6592010-11-18 00:42:18 +00002154 case VisitorJob::MemberRefVisitKind: {
2155 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2156 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2157 return true;
2158 continue;
2159 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002160 case VisitorJob::StmtVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002161 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002162 if (!S)
2163 continue;
2164
Ted Kremenekf1107452010-11-12 18:26:56 +00002165 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002166 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenekcdba6592010-11-18 00:42:18 +00002167 if (!IsInRegionOfInterest(Cursor))
2168 continue;
2169 switch (Visitor(Cursor, Parent, ClientData)) {
2170 case CXChildVisit_Break: return true;
2171 case CXChildVisit_Continue: break;
2172 case CXChildVisit_Recurse:
2173 EnqueueWorkList(WL, S);
Ted Kremenek82f3c502010-11-15 22:23:26 +00002174 break;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002175 }
Ted Kremenek82f3c502010-11-15 22:23:26 +00002176 continue;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002177 }
2178 case VisitorJob::MemberExprPartsKind: {
2179 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002180 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002181
2182 // Visit the nested-name-specifier
Douglas Gregor40d96a62011-02-28 21:54:11 +00002183 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002185 return true;
2186
2187 // Visit the declaration name.
2188 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2189 return true;
2190
2191 // Visit the explicitly-specified template arguments, if any.
2192 if (M->hasExplicitTemplateArgs()) {
2193 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2194 *ArgEnd = Arg + M->getNumTemplateArgs();
2195 Arg != ArgEnd; ++Arg) {
2196 if (VisitTemplateArgumentLoc(*Arg))
2197 return true;
2198 }
2199 }
2200 continue;
2201 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002202 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002203 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002204 // Visit nested-name-specifier, if present.
Douglas Gregor40d96a62011-02-28 21:54:11 +00002205 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2206 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002207 return true;
2208 // Visit declaration name.
2209 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2210 return true;
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002211 continue;
2212 }
Ted Kremenek60458782010-11-12 21:34:16 +00002213 case VisitorJob::OverloadExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002214 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenek60458782010-11-12 21:34:16 +00002215 // Visit the nested-name-specifier.
Douglas Gregor4c9be892011-02-28 20:01:57 +00002216 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2217 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek60458782010-11-12 21:34:16 +00002218 return true;
2219 // Visit the declaration name.
2220 if (VisitDeclarationNameInfo(O->getNameInfo()))
2221 return true;
2222 // Visit the overloaded declaration reference.
2223 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2224 return true;
Ted Kremenek60458782010-11-12 21:34:16 +00002225 continue;
2226 }
Douglas Gregor94d96292011-01-19 20:34:17 +00002227 case VisitorJob::SizeOfPackExprPartsKind: {
2228 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2229 NamedDecl *Pack = E->getPack();
2230 if (isa<TemplateTypeParmDecl>(Pack)) {
2231 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2232 E->getPackLoc(), TU)))
2233 return true;
2234
2235 continue;
2236 }
2237
2238 if (isa<TemplateTemplateParmDecl>(Pack)) {
2239 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2240 E->getPackLoc(), TU)))
2241 return true;
2242
2243 continue;
2244 }
2245
2246 // Non-type template parameter packs and function parameter packs are
2247 // treated like DeclRefExpr cursors.
2248 continue;
2249 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002250 }
2251 }
2252 return false;
2253}
2254
Ted Kremenekcdba6592010-11-18 00:42:18 +00002255bool CursorVisitor::Visit(Stmt *S) {
Ted Kremenekd1ded662010-11-15 23:31:32 +00002256 VisitorWorkList *WL = 0;
2257 if (!WorkListFreeList.empty()) {
2258 WL = WorkListFreeList.back();
2259 WL->clear();
2260 WorkListFreeList.pop_back();
2261 }
2262 else {
2263 WL = new VisitorWorkList();
2264 WorkListCache.push_back(WL);
2265 }
2266 EnqueueWorkList(*WL, S);
2267 bool result = RunVisitorWorkList(*WL);
2268 WorkListFreeList.push_back(WL);
2269 return result;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002270}
2271
2272//===----------------------------------------------------------------------===//
2273// Misc. API hooks.
2274//===----------------------------------------------------------------------===//
2275
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002276static llvm::sys::Mutex EnableMultithreadingMutex;
2277static bool EnabledMultithreading;
2278
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002279extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002280CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2281 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002282 // Disable pretty stack trace functionality, which will otherwise be a very
2283 // poor citizen of the world and set up all sorts of signal handlers.
2284 llvm::DisablePrettyStackTrace = true;
2285
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002286 // We use crash recovery to make some of our APIs more reliable, implicitly
2287 // enable it.
2288 llvm::CrashRecoveryContext::Enable();
2289
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002290 // Enable support for multithreading in LLVM.
2291 {
2292 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2293 if (!EnabledMultithreading) {
2294 llvm::llvm_start_multithreaded();
2295 EnabledMultithreading = true;
2296 }
2297 }
2298
Douglas Gregora030b7c2010-01-22 20:35:53 +00002299 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002300 if (excludeDeclarationsFromPCH)
2301 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002302 if (displayDiagnostics)
2303 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002304 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002305}
2306
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002307void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002308 if (CIdx)
2309 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002310}
2311
Ted Kremenekd2427dd2011-03-18 23:05:39 +00002312void clang_toggleCrashRecovery(unsigned isEnabled) {
2313 if (isEnabled)
2314 llvm::CrashRecoveryContext::Enable();
2315 else
2316 llvm::CrashRecoveryContext::Disable();
2317}
2318
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002319CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002320 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002321 if (!CIdx)
2322 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002323
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002324 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002325 FileSystemOptions FileSystemOpts;
2326 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002327
Douglas Gregor28019772010-04-05 23:52:57 +00002328 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremeneka60ed472010-11-16 08:15:36 +00002329 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002330 CXXIdx->getOnlyLocalDecls(),
2331 0, 0, true);
Ted Kremeneka60ed472010-11-16 08:15:36 +00002332 return MakeCXTranslationUnit(TU);
Steve Naroff600866c2009-08-27 19:51:58 +00002333}
2334
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002335unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002336 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002337 CXTranslationUnit_CacheCompletionResults |
2338 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002339}
2340
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002341CXTranslationUnit
2342clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2343 const char *source_filename,
2344 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002345 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002346 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002347 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor5a430212010-07-21 18:52:53 +00002348 return clang_parseTranslationUnit(CIdx, source_filename,
2349 command_line_args, num_command_line_args,
2350 unsaved_files, num_unsaved_files,
2351 CXTranslationUnit_DetailedPreprocessingRecord);
2352}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002353
2354struct ParseTranslationUnitInfo {
2355 CXIndex CIdx;
2356 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002357 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002358 int num_command_line_args;
2359 struct CXUnsavedFile *unsaved_files;
2360 unsigned num_unsaved_files;
2361 unsigned options;
2362 CXTranslationUnit result;
2363};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002364static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002365 ParseTranslationUnitInfo *PTUI =
2366 static_cast<ParseTranslationUnitInfo*>(UserData);
2367 CXIndex CIdx = PTUI->CIdx;
2368 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002369 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002370 int num_command_line_args = PTUI->num_command_line_args;
2371 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2372 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2373 unsigned options = PTUI->options;
2374 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002375
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002376 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002377 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002378
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002379 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2380
Douglas Gregor44c181a2010-07-23 00:33:23 +00002381 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002382 bool CompleteTranslationUnit
2383 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002384 bool CacheCodeCompetionResults
2385 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002386 bool CXXPrecompilePreamble
2387 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2388 bool CXXChainedPCH
2389 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002390
Douglas Gregor5352ac02010-01-28 00:27:43 +00002391 // Configure the diagnostics.
2392 DiagnosticOptions DiagOpts;
Ted Kremenek25a11e12011-03-22 01:15:24 +00002393 llvm::IntrusiveRefCntPtr<Diagnostic>
2394 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2395 command_line_args));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002396
Ted Kremenek25a11e12011-03-22 01:15:24 +00002397 // Recover resources if we crash before exiting this function.
2398 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2399 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2400 DiagCleanup(Diags.getPtr());
2401
2402 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2403 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2404
2405 // Recover resources if we crash before exiting this function.
2406 llvm::CrashRecoveryContextCleanupRegistrar<
2407 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2408
Douglas Gregor4db64a42010-01-23 00:14:00 +00002409 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002410 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002411 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002412 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002413 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2414 Buffer));
Douglas Gregor4db64a42010-01-23 00:14:00 +00002415 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002416
Ted Kremenek25a11e12011-03-22 01:15:24 +00002417 llvm::OwningPtr<std::vector<const char *> >
2418 Args(new std::vector<const char*>());
2419
2420 // Recover resources if we crash before exiting this method.
2421 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2422 ArgsCleanup(Args.get());
2423
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002424 // Since the Clang C library is primarily used by batch tools dealing with
2425 // (often very broken) source code, where spell-checking can have a
2426 // significant negative impact on performance (particularly when
2427 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002428 // Only do this if we haven't found a spell-checking-related argument.
2429 bool FoundSpellCheckingArgument = false;
2430 for (int I = 0; I != num_command_line_args; ++I) {
2431 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2432 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2433 FoundSpellCheckingArgument = true;
2434 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002435 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002436 }
2437 if (!FoundSpellCheckingArgument)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002438 Args->push_back("-fno-spell-checking");
Douglas Gregorb10daed2010-10-11 16:52:23 +00002439
Ted Kremenek25a11e12011-03-22 01:15:24 +00002440 Args->insert(Args->end(), command_line_args,
2441 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002442
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002443 // The 'source_filename' argument is optional. If the caller does not
2444 // specify it then it is assumed that the source file is specified
2445 // in the actual argument list.
2446 // Put the source file after command_line_args otherwise if '-x' flag is
2447 // present it will be unused.
2448 if (source_filename)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002449 Args->push_back(source_filename);
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002450
Douglas Gregor44c181a2010-07-23 00:33:23 +00002451 // Do we need the detailed preprocessing record?
2452 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek25a11e12011-03-22 01:15:24 +00002453 Args->push_back("-Xclang");
2454 Args->push_back("-detailed-preprocessing-record");
Douglas Gregor44c181a2010-07-23 00:33:23 +00002455 }
2456
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002457 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002458 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek4ee99262011-03-22 20:16:19 +00002459 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2460 /* vector::data() not portable */,
2461 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002462 Diags,
2463 CXXIdx->getClangResourcesPath(),
2464 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002465 /*CaptureDiagnostics=*/true,
Ted Kremenek4ee99262011-03-22 20:16:19 +00002466 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek25a11e12011-03-22 01:15:24 +00002467 RemappedFiles->size(),
Argyrios Kyrtzidis299a4a92011-03-08 23:35:24 +00002468 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002469 PrecompilePreamble,
2470 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002471 CacheCodeCompetionResults,
2472 CXXPrecompilePreamble,
2473 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002474
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002475 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002476 // Make sure to check that 'Unit' is non-NULL.
2477 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2478 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2479 DEnd = Unit->stored_diag_end();
2480 D != DEnd; ++D) {
2481 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2482 CXString Msg = clang_formatDiagnostic(&Diag,
2483 clang_defaultDiagnosticDisplayOptions());
2484 fprintf(stderr, "%s\n", clang_getCString(Msg));
2485 clang_disposeString(Msg);
2486 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002487#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002488 // On Windows, force a flush, since there may be multiple copies of
2489 // stderr and stdout in the file system, all with different buffers
2490 // but writing to the same device.
2491 fflush(stderr);
2492#endif
2493 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002494 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002495
Ted Kremeneka60ed472010-11-16 08:15:36 +00002496 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002497}
2498CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2499 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002500 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002501 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002502 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002503 unsigned num_unsaved_files,
2504 unsigned options) {
2505 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002506 num_command_line_args, unsaved_files,
2507 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002508 llvm::CrashRecoveryContext CRC;
2509
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002510 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002511 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2512 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2513 fprintf(stderr, " 'command_line_args' : [");
2514 for (int i = 0; i != num_command_line_args; ++i) {
2515 if (i)
2516 fprintf(stderr, ", ");
2517 fprintf(stderr, "'%s'", command_line_args[i]);
2518 }
2519 fprintf(stderr, "],\n");
2520 fprintf(stderr, " 'unsaved_files' : [");
2521 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2522 if (i)
2523 fprintf(stderr, ", ");
2524 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2525 unsaved_files[i].Length);
2526 }
2527 fprintf(stderr, "],\n");
2528 fprintf(stderr, " 'options' : %d,\n", options);
2529 fprintf(stderr, "}\n");
2530
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002531 return 0;
2532 }
2533
2534 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002535}
2536
Douglas Gregor19998442010-08-13 15:35:05 +00002537unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2538 return CXSaveTranslationUnit_None;
2539}
2540
2541int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2542 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002543 if (!TU)
2544 return 1;
2545
Ted Kremeneka60ed472010-11-16 08:15:36 +00002546 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002547}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002548
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002549void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002550 if (CTUnit) {
2551 // If the translation unit has been marked as unsafe to free, just discard
2552 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002553 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002554 return;
2555
Ted Kremeneka60ed472010-11-16 08:15:36 +00002556 delete static_cast<ASTUnit *>(CTUnit->TUData);
2557 disposeCXStringPool(CTUnit->StringPool);
2558 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002559 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002560}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002561
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002562unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2563 return CXReparse_None;
2564}
2565
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002566struct ReparseTranslationUnitInfo {
2567 CXTranslationUnit TU;
2568 unsigned num_unsaved_files;
2569 struct CXUnsavedFile *unsaved_files;
2570 unsigned options;
2571 int result;
2572};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002573
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002574static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002575 ReparseTranslationUnitInfo *RTUI =
2576 static_cast<ReparseTranslationUnitInfo*>(UserData);
2577 CXTranslationUnit TU = RTUI->TU;
2578 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2579 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2580 unsigned options = RTUI->options;
2581 (void) options;
2582 RTUI->result = 1;
2583
Douglas Gregorabc563f2010-07-19 21:46:24 +00002584 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002585 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002586
Ted Kremeneka60ed472010-11-16 08:15:36 +00002587 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002588 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002589
Ted Kremenek25a11e12011-03-22 01:15:24 +00002590 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2591 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2592
2593 // Recover resources if we crash before exiting this function.
2594 llvm::CrashRecoveryContextCleanupRegistrar<
2595 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2596
Douglas Gregorabc563f2010-07-19 21:46:24 +00002597 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2598 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2599 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002600 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002601 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2602 Buffer));
Douglas Gregorabc563f2010-07-19 21:46:24 +00002603 }
2604
Ted Kremenek4ee99262011-03-22 20:16:19 +00002605 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2606 RemappedFiles->size()))
Douglas Gregor593b0c12010-09-23 18:47:53 +00002607 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002608}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002609
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002610int clang_reparseTranslationUnit(CXTranslationUnit TU,
2611 unsigned num_unsaved_files,
2612 struct CXUnsavedFile *unsaved_files,
2613 unsigned options) {
2614 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2615 options, 0 };
2616 llvm::CrashRecoveryContext CRC;
2617
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002618 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002619 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002620 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002621 return 1;
2622 }
2623
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002624
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002625 return RTUI.result;
2626}
2627
Douglas Gregordf95a132010-08-09 20:45:32 +00002628
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002629CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002630 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002631 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002632
Ted Kremeneka60ed472010-11-16 08:15:36 +00002633 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002634 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002635}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002636
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002637CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002638 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002639 return Result;
2640}
2641
Ted Kremenekfb480492010-01-13 21:46:36 +00002642} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002643
Ted Kremenekfb480492010-01-13 21:46:36 +00002644//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002645// CXSourceLocation and CXSourceRange Operations.
2646//===----------------------------------------------------------------------===//
2647
Douglas Gregorb9790342010-01-22 21:44:22 +00002648extern "C" {
2649CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002650 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002651 return Result;
2652}
2653
2654unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002655 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2656 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2657 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002658}
2659
2660CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2661 CXFile file,
2662 unsigned line,
2663 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002664 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002665 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002666
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002667 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002668 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002669 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002670 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002671 = CXXUnit->getSourceManager().getLocation(File, line, column);
2672 if (SLoc.isInvalid()) {
2673 if (Logging)
2674 llvm::errs() << "clang_getLocation(\"" << File->getName()
2675 << "\", " << line << ", " << column << ") = invalid\n";
2676 return clang_getNullLocation();
2677 }
2678
2679 if (Logging)
2680 llvm::errs() << "clang_getLocation(\"" << File->getName()
2681 << "\", " << line << ", " << column << ") = "
2682 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002683
2684 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2685}
2686
2687CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2688 CXFile file,
2689 unsigned offset) {
2690 if (!tu || !file)
2691 return clang_getNullLocation();
2692
Ted Kremeneka60ed472010-11-16 08:15:36 +00002693 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002694 SourceLocation Start
2695 = CXXUnit->getSourceManager().getLocation(
2696 static_cast<const FileEntry *>(file),
2697 1, 1);
2698 if (Start.isInvalid()) return clang_getNullLocation();
2699
2700 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2701
2702 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002703
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002704 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002705}
2706
Douglas Gregor5352ac02010-01-28 00:27:43 +00002707CXSourceRange clang_getNullRange() {
2708 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2709 return Result;
2710}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002711
Douglas Gregor5352ac02010-01-28 00:27:43 +00002712CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2713 if (begin.ptr_data[0] != end.ptr_data[0] ||
2714 begin.ptr_data[1] != end.ptr_data[1])
2715 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002716
2717 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002718 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002719 return Result;
2720}
2721
Douglas Gregor46766dc2010-01-26 19:19:08 +00002722void clang_getInstantiationLocation(CXSourceLocation location,
2723 CXFile *file,
2724 unsigned *line,
2725 unsigned *column,
2726 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002727 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2728
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002729 if (!location.ptr_data[0] || Loc.isInvalid()) {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002730 if (file)
2731 *file = 0;
2732 if (line)
2733 *line = 0;
2734 if (column)
2735 *column = 0;
2736 if (offset)
2737 *offset = 0;
2738 return;
2739 }
2740
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002741 const SourceManager &SM =
2742 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002743 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002744
2745 if (file)
2746 *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));
2747 if (line)
2748 *line = SM.getInstantiationLineNumber(InstLoc);
2749 if (column)
2750 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002751 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002752 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002753}
2754
Douglas Gregora9b06d42010-11-09 06:24:54 +00002755void clang_getSpellingLocation(CXSourceLocation location,
2756 CXFile *file,
2757 unsigned *line,
2758 unsigned *column,
2759 unsigned *offset) {
2760 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2761
2762 if (!location.ptr_data[0] || Loc.isInvalid()) {
2763 if (file)
2764 *file = 0;
2765 if (line)
2766 *line = 0;
2767 if (column)
2768 *column = 0;
2769 if (offset)
2770 *offset = 0;
2771 return;
2772 }
2773
2774 const SourceManager &SM =
2775 *static_cast<const SourceManager*>(location.ptr_data[0]);
2776 SourceLocation SpellLoc = Loc;
2777 if (SpellLoc.isMacroID()) {
2778 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2779 if (SimpleSpellingLoc.isFileID() &&
2780 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2781 SpellLoc = SimpleSpellingLoc;
2782 else
2783 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2784 }
2785
2786 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2787 FileID FID = LocInfo.first;
2788 unsigned FileOffset = LocInfo.second;
2789
2790 if (file)
2791 *file = (void *)SM.getFileEntryForID(FID);
2792 if (line)
2793 *line = SM.getLineNumber(FID, FileOffset);
2794 if (column)
2795 *column = SM.getColumnNumber(FID, FileOffset);
2796 if (offset)
2797 *offset = FileOffset;
2798}
2799
Douglas Gregor1db19de2010-01-19 21:36:55 +00002800CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002801 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002802 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002803 return Result;
2804}
2805
2806CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002807 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002808 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002809 return Result;
2810}
2811
Douglas Gregorb9790342010-01-22 21:44:22 +00002812} // end: extern "C"
2813
Douglas Gregor1db19de2010-01-19 21:36:55 +00002814//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002815// CXFile Operations.
2816//===----------------------------------------------------------------------===//
2817
2818extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002819CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002820 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002821 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002822
Steve Naroff88145032009-10-27 14:35:18 +00002823 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002824 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002825}
2826
2827time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002828 if (!SFile)
2829 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002830
Steve Naroff88145032009-10-27 14:35:18 +00002831 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2832 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002833}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002834
Douglas Gregorb9790342010-01-22 21:44:22 +00002835CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2836 if (!tu)
2837 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002838
Ted Kremeneka60ed472010-11-16 08:15:36 +00002839 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002840
Douglas Gregorb9790342010-01-22 21:44:22 +00002841 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002842 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002843}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002844
Ted Kremenekfb480492010-01-13 21:46:36 +00002845} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002846
Ted Kremenekfb480492010-01-13 21:46:36 +00002847//===----------------------------------------------------------------------===//
2848// CXCursor Operations.
2849//===----------------------------------------------------------------------===//
2850
Ted Kremenekfb480492010-01-13 21:46:36 +00002851static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002852 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2853 return getDeclFromExpr(CE->getSubExpr());
2854
Ted Kremenekfb480492010-01-13 21:46:36 +00002855 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2856 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002857 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2858 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002859 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2860 return ME->getMemberDecl();
2861 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2862 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002863 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002864 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002865
Ted Kremenekfb480492010-01-13 21:46:36 +00002866 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2867 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002868 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2869 if (!CE->isElidable())
2870 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002871 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2872 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002873
Douglas Gregordb1314e2010-10-01 21:11:22 +00002874 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2875 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002876 if (SubstNonTypeTemplateParmPackExpr *NTTP
2877 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2878 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002879 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2880 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2881 isa<ParmVarDecl>(SizeOfPack->getPack()))
2882 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002883
Ted Kremenekfb480492010-01-13 21:46:36 +00002884 return 0;
2885}
2886
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002887static SourceLocation getLocationFromExpr(Expr *E) {
2888 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2889 return /*FIXME:*/Msg->getLeftLoc();
2890 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2891 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002892 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2893 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002894 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2895 return Member->getMemberLoc();
2896 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2897 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002898 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2899 return SizeOfPack->getPackLoc();
2900
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002901 return E->getLocStart();
2902}
2903
Ted Kremenekfb480492010-01-13 21:46:36 +00002904extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002905
2906unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002907 CXCursorVisitor visitor,
2908 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002909 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00002910 getCursorASTUnit(parent)->getMaxPCHLevel(),
2911 false);
Douglas Gregorb1373d02010-01-20 20:59:29 +00002912 return CursorVis.VisitChildren(parent);
2913}
2914
David Chisnall3387c652010-11-03 14:12:26 +00002915#ifndef __has_feature
2916#define __has_feature(x) 0
2917#endif
2918#if __has_feature(blocks)
2919typedef enum CXChildVisitResult
2920 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2921
2922static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2923 CXClientData client_data) {
2924 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2925 return block(cursor, parent);
2926}
2927#else
2928// If we are compiled with a compiler that doesn't have native blocks support,
2929// define and call the block manually, so the
2930typedef struct _CXChildVisitResult
2931{
2932 void *isa;
2933 int flags;
2934 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002935 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2936 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002937} *CXCursorVisitorBlock;
2938
2939static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2940 CXClientData client_data) {
2941 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2942 return block->invoke(block, cursor, parent);
2943}
2944#endif
2945
2946
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002947unsigned clang_visitChildrenWithBlock(CXCursor parent,
2948 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002949 return clang_visitChildren(parent, visitWithBlock, block);
2950}
2951
Douglas Gregor78205d42010-01-20 21:45:58 +00002952static CXString getDeclSpelling(Decl *D) {
2953 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00002954 if (!ND) {
2955 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2956 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2957 return createCXString(Property->getIdentifier()->getName());
2958
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002959 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00002960 }
2961
Douglas Gregor78205d42010-01-20 21:45:58 +00002962 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002963 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002964
Douglas Gregor78205d42010-01-20 21:45:58 +00002965 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2966 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2967 // and returns different names. NamedDecl returns the class name and
2968 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002969 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002970
Douglas Gregor0a35bce2010-09-01 03:07:18 +00002971 if (isa<UsingDirectiveDecl>(D))
2972 return createCXString("");
2973
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00002974 llvm::SmallString<1024> S;
2975 llvm::raw_svector_ostream os(S);
2976 ND->printName(os);
2977
2978 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00002979}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002980
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002981CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002982 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00002983 return clang_getTranslationUnitSpelling(
2984 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002985
Steve Narofff334b4e2009-09-02 18:26:48 +00002986 if (clang_isReference(C.kind)) {
2987 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00002988 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00002989 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002990 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002991 }
2992 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00002993 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002994 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002995 }
2996 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00002997 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00002998 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002999 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003000 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00003001 case CXCursor_CXXBaseSpecifier: {
3002 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3003 return createCXString(B->getType().getAsString());
3004 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003005 case CXCursor_TypeRef: {
3006 TypeDecl *Type = getCursorTypeRef(C).first;
3007 assert(Type && "Missing type decl");
3008
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003009 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3010 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003011 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003012 case CXCursor_TemplateRef: {
3013 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00003014 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003015
3016 return createCXString(Template->getNameAsString());
3017 }
Douglas Gregor69319002010-08-31 23:48:11 +00003018
3019 case CXCursor_NamespaceRef: {
3020 NamedDecl *NS = getCursorNamespaceRef(C).first;
3021 assert(NS && "Missing namespace decl");
3022
3023 return createCXString(NS->getNameAsString());
3024 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003025
Douglas Gregora67e03f2010-09-09 21:42:20 +00003026 case CXCursor_MemberRef: {
3027 FieldDecl *Field = getCursorMemberRef(C).first;
3028 assert(Field && "Missing member decl");
3029
3030 return createCXString(Field->getNameAsString());
3031 }
3032
Douglas Gregor36897b02010-09-10 00:22:18 +00003033 case CXCursor_LabelRef: {
3034 LabelStmt *Label = getCursorLabelRef(C).first;
3035 assert(Label && "Missing label");
3036
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003037 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003038 }
3039
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003040 case CXCursor_OverloadedDeclRef: {
3041 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3042 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3043 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3044 return createCXString(ND->getNameAsString());
3045 return createCXString("");
3046 }
3047 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3048 return createCXString(E->getName().getAsString());
3049 OverloadedTemplateStorage *Ovl
3050 = Storage.get<OverloadedTemplateStorage*>();
3051 if (Ovl->size() == 0)
3052 return createCXString("");
3053 return createCXString((*Ovl->begin())->getNameAsString());
3054 }
3055
Daniel Dunbaracca7252009-11-30 20:42:49 +00003056 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003057 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003058 }
3059 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003060
3061 if (clang_isExpression(C.kind)) {
3062 Decl *D = getDeclFromExpr(getCursorExpr(C));
3063 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003064 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003065 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003066 }
3067
Douglas Gregor36897b02010-09-10 00:22:18 +00003068 if (clang_isStatement(C.kind)) {
3069 Stmt *S = getCursorStmt(C);
3070 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003071 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003072
3073 return createCXString("");
3074 }
3075
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003076 if (C.kind == CXCursor_MacroInstantiation)
3077 return createCXString(getCursorMacroInstantiation(C)->getName()
3078 ->getNameStart());
3079
Douglas Gregor572feb22010-03-18 18:04:21 +00003080 if (C.kind == CXCursor_MacroDefinition)
3081 return createCXString(getCursorMacroDefinition(C)->getName()
3082 ->getNameStart());
3083
Douglas Gregorecdcb882010-10-20 22:00:55 +00003084 if (C.kind == CXCursor_InclusionDirective)
3085 return createCXString(getCursorInclusionDirective(C)->getFileName());
3086
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003087 if (clang_isDeclaration(C.kind))
3088 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003089
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003090 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003091}
3092
Douglas Gregor358559d2010-10-02 22:49:11 +00003093CXString clang_getCursorDisplayName(CXCursor C) {
3094 if (!clang_isDeclaration(C.kind))
3095 return clang_getCursorSpelling(C);
3096
3097 Decl *D = getCursorDecl(C);
3098 if (!D)
3099 return createCXString("");
3100
3101 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3102 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3103 D = FunTmpl->getTemplatedDecl();
3104
3105 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3106 llvm::SmallString<64> Str;
3107 llvm::raw_svector_ostream OS(Str);
3108 OS << Function->getNameAsString();
3109 if (Function->getPrimaryTemplate())
3110 OS << "<>";
3111 OS << "(";
3112 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3113 if (I)
3114 OS << ", ";
3115 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3116 }
3117
3118 if (Function->isVariadic()) {
3119 if (Function->getNumParams())
3120 OS << ", ";
3121 OS << "...";
3122 }
3123 OS << ")";
3124 return createCXString(OS.str());
3125 }
3126
3127 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3128 llvm::SmallString<64> Str;
3129 llvm::raw_svector_ostream OS(Str);
3130 OS << ClassTemplate->getNameAsString();
3131 OS << "<";
3132 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3133 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3134 if (I)
3135 OS << ", ";
3136
3137 NamedDecl *Param = Params->getParam(I);
3138 if (Param->getIdentifier()) {
3139 OS << Param->getIdentifier()->getName();
3140 continue;
3141 }
3142
3143 // There is no parameter name, which makes this tricky. Try to come up
3144 // with something useful that isn't too long.
3145 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3146 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3147 else if (NonTypeTemplateParmDecl *NTTP
3148 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3149 OS << NTTP->getType().getAsString(Policy);
3150 else
3151 OS << "template<...> class";
3152 }
3153
3154 OS << ">";
3155 return createCXString(OS.str());
3156 }
3157
3158 if (ClassTemplateSpecializationDecl *ClassSpec
3159 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3160 // If the type was explicitly written, use that.
3161 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3162 return createCXString(TSInfo->getType().getAsString(Policy));
3163
3164 llvm::SmallString<64> Str;
3165 llvm::raw_svector_ostream OS(Str);
3166 OS << ClassSpec->getNameAsString();
3167 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003168 ClassSpec->getTemplateArgs().data(),
3169 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003170 Policy);
3171 return createCXString(OS.str());
3172 }
3173
3174 return clang_getCursorSpelling(C);
3175}
3176
Ted Kremeneke68fff62010-02-17 00:41:32 +00003177CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003178 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003179 case CXCursor_FunctionDecl:
3180 return createCXString("FunctionDecl");
3181 case CXCursor_TypedefDecl:
3182 return createCXString("TypedefDecl");
3183 case CXCursor_EnumDecl:
3184 return createCXString("EnumDecl");
3185 case CXCursor_EnumConstantDecl:
3186 return createCXString("EnumConstantDecl");
3187 case CXCursor_StructDecl:
3188 return createCXString("StructDecl");
3189 case CXCursor_UnionDecl:
3190 return createCXString("UnionDecl");
3191 case CXCursor_ClassDecl:
3192 return createCXString("ClassDecl");
3193 case CXCursor_FieldDecl:
3194 return createCXString("FieldDecl");
3195 case CXCursor_VarDecl:
3196 return createCXString("VarDecl");
3197 case CXCursor_ParmDecl:
3198 return createCXString("ParmDecl");
3199 case CXCursor_ObjCInterfaceDecl:
3200 return createCXString("ObjCInterfaceDecl");
3201 case CXCursor_ObjCCategoryDecl:
3202 return createCXString("ObjCCategoryDecl");
3203 case CXCursor_ObjCProtocolDecl:
3204 return createCXString("ObjCProtocolDecl");
3205 case CXCursor_ObjCPropertyDecl:
3206 return createCXString("ObjCPropertyDecl");
3207 case CXCursor_ObjCIvarDecl:
3208 return createCXString("ObjCIvarDecl");
3209 case CXCursor_ObjCInstanceMethodDecl:
3210 return createCXString("ObjCInstanceMethodDecl");
3211 case CXCursor_ObjCClassMethodDecl:
3212 return createCXString("ObjCClassMethodDecl");
3213 case CXCursor_ObjCImplementationDecl:
3214 return createCXString("ObjCImplementationDecl");
3215 case CXCursor_ObjCCategoryImplDecl:
3216 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003217 case CXCursor_CXXMethod:
3218 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003219 case CXCursor_UnexposedDecl:
3220 return createCXString("UnexposedDecl");
3221 case CXCursor_ObjCSuperClassRef:
3222 return createCXString("ObjCSuperClassRef");
3223 case CXCursor_ObjCProtocolRef:
3224 return createCXString("ObjCProtocolRef");
3225 case CXCursor_ObjCClassRef:
3226 return createCXString("ObjCClassRef");
3227 case CXCursor_TypeRef:
3228 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003229 case CXCursor_TemplateRef:
3230 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003231 case CXCursor_NamespaceRef:
3232 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003233 case CXCursor_MemberRef:
3234 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003235 case CXCursor_LabelRef:
3236 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003237 case CXCursor_OverloadedDeclRef:
3238 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003239 case CXCursor_UnexposedExpr:
3240 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003241 case CXCursor_BlockExpr:
3242 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003243 case CXCursor_DeclRefExpr:
3244 return createCXString("DeclRefExpr");
3245 case CXCursor_MemberRefExpr:
3246 return createCXString("MemberRefExpr");
3247 case CXCursor_CallExpr:
3248 return createCXString("CallExpr");
3249 case CXCursor_ObjCMessageExpr:
3250 return createCXString("ObjCMessageExpr");
3251 case CXCursor_UnexposedStmt:
3252 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003253 case CXCursor_LabelStmt:
3254 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003255 case CXCursor_InvalidFile:
3256 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003257 case CXCursor_InvalidCode:
3258 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003259 case CXCursor_NoDeclFound:
3260 return createCXString("NoDeclFound");
3261 case CXCursor_NotImplemented:
3262 return createCXString("NotImplemented");
3263 case CXCursor_TranslationUnit:
3264 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003265 case CXCursor_UnexposedAttr:
3266 return createCXString("UnexposedAttr");
3267 case CXCursor_IBActionAttr:
3268 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003269 case CXCursor_IBOutletAttr:
3270 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003271 case CXCursor_IBOutletCollectionAttr:
3272 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003273 case CXCursor_PreprocessingDirective:
3274 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003275 case CXCursor_MacroDefinition:
3276 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003277 case CXCursor_MacroInstantiation:
3278 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003279 case CXCursor_InclusionDirective:
3280 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003281 case CXCursor_Namespace:
3282 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003283 case CXCursor_LinkageSpec:
3284 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003285 case CXCursor_CXXBaseSpecifier:
3286 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003287 case CXCursor_Constructor:
3288 return createCXString("CXXConstructor");
3289 case CXCursor_Destructor:
3290 return createCXString("CXXDestructor");
3291 case CXCursor_ConversionFunction:
3292 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003293 case CXCursor_TemplateTypeParameter:
3294 return createCXString("TemplateTypeParameter");
3295 case CXCursor_NonTypeTemplateParameter:
3296 return createCXString("NonTypeTemplateParameter");
3297 case CXCursor_TemplateTemplateParameter:
3298 return createCXString("TemplateTemplateParameter");
3299 case CXCursor_FunctionTemplate:
3300 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003301 case CXCursor_ClassTemplate:
3302 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003303 case CXCursor_ClassTemplatePartialSpecialization:
3304 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003305 case CXCursor_NamespaceAlias:
3306 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003307 case CXCursor_UsingDirective:
3308 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003309 case CXCursor_UsingDeclaration:
3310 return createCXString("UsingDeclaration");
Steve Naroff89922f82009-08-31 00:59:03 +00003311 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003312
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003313 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003314 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003315}
Steve Naroff89922f82009-08-31 00:59:03 +00003316
Ted Kremeneke68fff62010-02-17 00:41:32 +00003317enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3318 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003319 CXClientData client_data) {
3320 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003321
3322 // If our current best cursor is the construction of a temporary object,
3323 // don't replace that cursor with a type reference, because we want
3324 // clang_getCursor() to point at the constructor.
3325 if (clang_isExpression(BestCursor->kind) &&
3326 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3327 cursor.kind == CXCursor_TypeRef)
3328 return CXChildVisit_Recurse;
3329
Douglas Gregor85fe1562010-12-10 07:23:11 +00003330 // Don't override a preprocessing cursor with another preprocessing
3331 // cursor; we want the outermost preprocessing cursor.
3332 if (clang_isPreprocessing(cursor.kind) &&
3333 clang_isPreprocessing(BestCursor->kind))
3334 return CXChildVisit_Recurse;
3335
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003336 *BestCursor = cursor;
3337 return CXChildVisit_Recurse;
3338}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003339
Douglas Gregorb9790342010-01-22 21:44:22 +00003340CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3341 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003342 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003343
Ted Kremeneka60ed472010-11-16 08:15:36 +00003344 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003345 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3346
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003347 // Translate the given source location to make it point at the beginning of
3348 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003349 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003350
3351 // Guard against an invalid SourceLocation, or we may assert in one
3352 // of the following calls.
3353 if (SLoc.isInvalid())
3354 return clang_getNullCursor();
3355
Douglas Gregor40749ee2010-11-03 00:35:38 +00003356 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003357 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3358 CXXUnit->getASTContext().getLangOptions());
3359
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003360 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3361 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003362 // FIXME: Would be great to have a "hint" cursor, then walk from that
3363 // hint cursor upward until we find a cursor whose source range encloses
3364 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003365 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3366 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00003367 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003368 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003369 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003370
3371 if (Logging) {
3372 CXFile SearchFile;
3373 unsigned SearchLine, SearchColumn;
3374 CXFile ResultFile;
3375 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003376 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3377 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003378 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3379
3380 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3381 0);
3382 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3383 &ResultColumn, 0);
3384 SearchFileName = clang_getFileName(SearchFile);
3385 ResultFileName = clang_getFileName(ResultFile);
3386 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003387 USR = clang_getCursorUSR(Result);
3388 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003389 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3390 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003391 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3392 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003393 clang_disposeString(SearchFileName);
3394 clang_disposeString(ResultFileName);
3395 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003396 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003397
3398 CXCursor Definition = clang_getCursorDefinition(Result);
3399 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3400 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3401 CXString DefinitionKindSpelling
3402 = clang_getCursorKindSpelling(Definition.kind);
3403 CXFile DefinitionFile;
3404 unsigned DefinitionLine, DefinitionColumn;
3405 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3406 &DefinitionLine, &DefinitionColumn, 0);
3407 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3408 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3409 clang_getCString(DefinitionKindSpelling),
3410 clang_getCString(DefinitionFileName),
3411 DefinitionLine, DefinitionColumn);
3412 clang_disposeString(DefinitionFileName);
3413 clang_disposeString(DefinitionKindSpelling);
3414 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003415 }
3416
Ted Kremeneke68fff62010-02-17 00:41:32 +00003417 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003418}
3419
Ted Kremenek73885552009-11-17 19:28:59 +00003420CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003421 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003422}
3423
3424unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003425 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003426}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003427
Douglas Gregor9ce55842010-11-20 00:09:34 +00003428unsigned clang_hashCursor(CXCursor C) {
3429 unsigned Index = 0;
3430 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3431 Index = 1;
3432
3433 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3434 std::make_pair(C.kind, C.data[Index]));
3435}
3436
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003437unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003438 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3439}
3440
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003441unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003442 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3443}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003444
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003445unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003446 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3447}
3448
Douglas Gregor97b98722010-01-19 23:20:36 +00003449unsigned clang_isExpression(enum CXCursorKind K) {
3450 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3451}
3452
3453unsigned clang_isStatement(enum CXCursorKind K) {
3454 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3455}
3456
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003457unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3458 return K == CXCursor_TranslationUnit;
3459}
3460
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003461unsigned clang_isPreprocessing(enum CXCursorKind K) {
3462 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3463}
3464
Ted Kremenekad6eff62010-03-08 21:17:29 +00003465unsigned clang_isUnexposed(enum CXCursorKind K) {
3466 switch (K) {
3467 case CXCursor_UnexposedDecl:
3468 case CXCursor_UnexposedExpr:
3469 case CXCursor_UnexposedStmt:
3470 case CXCursor_UnexposedAttr:
3471 return true;
3472 default:
3473 return false;
3474 }
3475}
3476
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003477CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003478 return C.kind;
3479}
3480
Douglas Gregor98258af2010-01-18 22:46:11 +00003481CXSourceLocation clang_getCursorLocation(CXCursor C) {
3482 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003483 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003484 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003485 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3486 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003487 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003488 }
3489
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003490 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003491 std::pair<ObjCProtocolDecl *, SourceLocation> P
3492 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003493 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003494 }
3495
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003496 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003497 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3498 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003499 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003500 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003501
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003502 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003503 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003504 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003505 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003506
3507 case CXCursor_TemplateRef: {
3508 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3509 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3510 }
3511
Douglas Gregor69319002010-08-31 23:48:11 +00003512 case CXCursor_NamespaceRef: {
3513 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3514 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3515 }
3516
Douglas Gregora67e03f2010-09-09 21:42:20 +00003517 case CXCursor_MemberRef: {
3518 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3519 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3520 }
3521
Ted Kremenek3064ef92010-08-27 21:34:58 +00003522 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003523 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3524 if (!BaseSpec)
3525 return clang_getNullLocation();
3526
3527 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3528 return cxloc::translateSourceLocation(getCursorContext(C),
3529 TSInfo->getTypeLoc().getBeginLoc());
3530
3531 return cxloc::translateSourceLocation(getCursorContext(C),
3532 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003533 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003534
Douglas Gregor36897b02010-09-10 00:22:18 +00003535 case CXCursor_LabelRef: {
3536 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3537 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3538 }
3539
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003540 case CXCursor_OverloadedDeclRef:
3541 return cxloc::translateSourceLocation(getCursorContext(C),
3542 getCursorOverloadedDeclRef(C).second);
3543
Douglas Gregorf46034a2010-01-18 23:41:10 +00003544 default:
3545 // FIXME: Need a way to enumerate all non-reference cases.
3546 llvm_unreachable("Missed a reference kind");
3547 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003548 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003549
3550 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003551 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003552 getLocationFromExpr(getCursorExpr(C)));
3553
Douglas Gregor36897b02010-09-10 00:22:18 +00003554 if (clang_isStatement(C.kind))
3555 return cxloc::translateSourceLocation(getCursorContext(C),
3556 getCursorStmt(C)->getLocStart());
3557
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003558 if (C.kind == CXCursor_PreprocessingDirective) {
3559 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3560 return cxloc::translateSourceLocation(getCursorContext(C), L);
3561 }
Douglas Gregor48072312010-03-18 15:23:44 +00003562
3563 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003564 SourceLocation L
3565 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003566 return cxloc::translateSourceLocation(getCursorContext(C), L);
3567 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003568
3569 if (C.kind == CXCursor_MacroDefinition) {
3570 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3571 return cxloc::translateSourceLocation(getCursorContext(C), L);
3572 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003573
3574 if (C.kind == CXCursor_InclusionDirective) {
3575 SourceLocation L
3576 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3577 return cxloc::translateSourceLocation(getCursorContext(C), L);
3578 }
3579
Ted Kremenek9a700d22010-05-12 06:16:13 +00003580 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003581 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003582
Douglas Gregorf46034a2010-01-18 23:41:10 +00003583 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003584 SourceLocation Loc = D->getLocation();
3585 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3586 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003587 // FIXME: Multiple variables declared in a single declaration
3588 // currently lack the information needed to correctly determine their
3589 // ranges when accounting for the type-specifier. We use context
3590 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3591 // and if so, whether it is the first decl.
3592 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3593 if (!cxcursor::isFirstInDeclGroup(C))
3594 Loc = VD->getLocation();
3595 }
3596
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003597 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003598}
Douglas Gregora7bde202010-01-19 00:34:46 +00003599
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003600} // end extern "C"
3601
3602static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003603 if (clang_isReference(C.kind)) {
3604 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003605 case CXCursor_ObjCSuperClassRef:
3606 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003607
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003608 case CXCursor_ObjCProtocolRef:
3609 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003610
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003611 case CXCursor_ObjCClassRef:
3612 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003613
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003614 case CXCursor_TypeRef:
3615 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003616
3617 case CXCursor_TemplateRef:
3618 return getCursorTemplateRef(C).second;
3619
Douglas Gregor69319002010-08-31 23:48:11 +00003620 case CXCursor_NamespaceRef:
3621 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003622
3623 case CXCursor_MemberRef:
3624 return getCursorMemberRef(C).second;
3625
Ted Kremenek3064ef92010-08-27 21:34:58 +00003626 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003627 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003628
Douglas Gregor36897b02010-09-10 00:22:18 +00003629 case CXCursor_LabelRef:
3630 return getCursorLabelRef(C).second;
3631
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003632 case CXCursor_OverloadedDeclRef:
3633 return getCursorOverloadedDeclRef(C).second;
3634
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003635 default:
3636 // FIXME: Need a way to enumerate all non-reference cases.
3637 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003638 }
3639 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003640
3641 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003642 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003643
3644 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003645 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003646
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003647 if (C.kind == CXCursor_PreprocessingDirective)
3648 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003649
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003650 if (C.kind == CXCursor_MacroInstantiation)
3651 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003652
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003653 if (C.kind == CXCursor_MacroDefinition)
3654 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003655
3656 if (C.kind == CXCursor_InclusionDirective)
3657 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3658
Ted Kremenek007a7c92010-11-01 23:26:51 +00003659 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3660 Decl *D = cxcursor::getCursorDecl(C);
3661 SourceRange R = D->getSourceRange();
3662 // FIXME: Multiple variables declared in a single declaration
3663 // currently lack the information needed to correctly determine their
3664 // ranges when accounting for the type-specifier. We use context
3665 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3666 // and if so, whether it is the first decl.
3667 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3668 if (!cxcursor::isFirstInDeclGroup(C))
3669 R.setBegin(VD->getLocation());
3670 }
3671 return R;
3672 }
Douglas Gregor66537982010-11-17 17:14:07 +00003673 return SourceRange();
3674}
3675
3676/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3677/// the decl-specifier-seq for declarations.
3678static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3679 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3680 Decl *D = cxcursor::getCursorDecl(C);
3681 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003682
Douglas Gregor2494dd02011-03-01 01:34:45 +00003683 // Adjust the start of the location for declarations preceded by
3684 // declaration specifiers.
3685 SourceLocation StartLoc;
3686 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3687 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3688 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3689 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3690 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3691 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3692 }
3693
3694 if (StartLoc.isValid() && R.getBegin().isValid() &&
3695 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3696 R.setBegin(StartLoc);
3697
3698 // FIXME: Multiple variables declared in a single declaration
3699 // currently lack the information needed to correctly determine their
3700 // ranges when accounting for the type-specifier. We use context
3701 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3702 // and if so, whether it is the first decl.
3703 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3704 if (!cxcursor::isFirstInDeclGroup(C))
3705 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003706 }
3707
3708 return R;
3709 }
3710
3711 return getRawCursorExtent(C);
3712}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003713
3714extern "C" {
3715
3716CXSourceRange clang_getCursorExtent(CXCursor C) {
3717 SourceRange R = getRawCursorExtent(C);
3718 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003719 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003720
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003721 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003722}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003723
3724CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003725 if (clang_isInvalid(C.kind))
3726 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003727
Ted Kremeneka60ed472010-11-16 08:15:36 +00003728 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003729 if (clang_isDeclaration(C.kind)) {
3730 Decl *D = getCursorDecl(C);
3731 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003732 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003733 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003734 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003735 if (ObjCForwardProtocolDecl *Protocols
3736 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003737 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003738 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3739 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3740 return MakeCXCursor(Property, tu);
3741
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003742 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003743 }
3744
Douglas Gregor97b98722010-01-19 23:20:36 +00003745 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003746 Expr *E = getCursorExpr(C);
3747 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003748 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003749 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003750
3751 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003752 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003753
Douglas Gregor97b98722010-01-19 23:20:36 +00003754 return clang_getNullCursor();
3755 }
3756
Douglas Gregor36897b02010-09-10 00:22:18 +00003757 if (clang_isStatement(C.kind)) {
3758 Stmt *S = getCursorStmt(C);
3759 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek37c2e962011-03-15 23:47:49 +00003760 if (LabelDecl *label = Goto->getLabel())
3761 if (LabelStmt *labelS = label->getStmt())
3762 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003763
3764 return clang_getNullCursor();
3765 }
3766
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003767 if (C.kind == CXCursor_MacroInstantiation) {
3768 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003769 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003770 }
3771
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003772 if (!clang_isReference(C.kind))
3773 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003774
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003775 switch (C.kind) {
3776 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003777 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003778
3779 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003780 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003781
3782 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003783 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003784
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003785 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003786 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003787
3788 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003789 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003790
Douglas Gregor69319002010-08-31 23:48:11 +00003791 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003792 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003793
Douglas Gregora67e03f2010-09-09 21:42:20 +00003794 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003795 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003796
Ted Kremenek3064ef92010-08-27 21:34:58 +00003797 case CXCursor_CXXBaseSpecifier: {
3798 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3799 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003800 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003801 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003802
Douglas Gregor36897b02010-09-10 00:22:18 +00003803 case CXCursor_LabelRef:
3804 // FIXME: We end up faking the "parent" declaration here because we
3805 // don't want to make CXCursor larger.
3806 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003807 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3808 .getTranslationUnitDecl(),
3809 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003810
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003811 case CXCursor_OverloadedDeclRef:
3812 return C;
3813
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003814 default:
3815 // We would prefer to enumerate all non-reference cursor kinds here.
3816 llvm_unreachable("Unhandled reference cursor kind");
3817 break;
3818 }
3819 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003820
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003821 return clang_getNullCursor();
3822}
3823
Douglas Gregorb6998662010-01-19 19:34:47 +00003824CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003825 if (clang_isInvalid(C.kind))
3826 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003827
Ted Kremeneka60ed472010-11-16 08:15:36 +00003828 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003829
Douglas Gregorb6998662010-01-19 19:34:47 +00003830 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003831 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003832 C = clang_getCursorReferenced(C);
3833 WasReference = true;
3834 }
3835
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003836 if (C.kind == CXCursor_MacroInstantiation)
3837 return clang_getCursorReferenced(C);
3838
Douglas Gregorb6998662010-01-19 19:34:47 +00003839 if (!clang_isDeclaration(C.kind))
3840 return clang_getNullCursor();
3841
3842 Decl *D = getCursorDecl(C);
3843 if (!D)
3844 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003845
Douglas Gregorb6998662010-01-19 19:34:47 +00003846 switch (D->getKind()) {
3847 // Declaration kinds that don't really separate the notions of
3848 // declaration and definition.
3849 case Decl::Namespace:
3850 case Decl::Typedef:
3851 case Decl::TemplateTypeParm:
3852 case Decl::EnumConstant:
3853 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003854 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003855 case Decl::ObjCIvar:
3856 case Decl::ObjCAtDefsField:
3857 case Decl::ImplicitParam:
3858 case Decl::ParmVar:
3859 case Decl::NonTypeTemplateParm:
3860 case Decl::TemplateTemplateParm:
3861 case Decl::ObjCCategoryImpl:
3862 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003863 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003864 case Decl::LinkageSpec:
3865 case Decl::ObjCPropertyImpl:
3866 case Decl::FileScopeAsm:
3867 case Decl::StaticAssert:
3868 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003869 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003870 return C;
3871
3872 // Declaration kinds that don't make any sense here, but are
3873 // nonetheless harmless.
3874 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003875 break;
3876
3877 // Declaration kinds for which the definition is not resolvable.
3878 case Decl::UnresolvedUsingTypename:
3879 case Decl::UnresolvedUsingValue:
3880 break;
3881
3882 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003883 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003884 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003885
3886 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003887 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003888
3889 case Decl::Enum:
3890 case Decl::Record:
3891 case Decl::CXXRecord:
3892 case Decl::ClassTemplateSpecialization:
3893 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003894 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003895 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003896 return clang_getNullCursor();
3897
3898 case Decl::Function:
3899 case Decl::CXXMethod:
3900 case Decl::CXXConstructor:
3901 case Decl::CXXDestructor:
3902 case Decl::CXXConversion: {
3903 const FunctionDecl *Def = 0;
3904 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003905 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003906 return clang_getNullCursor();
3907 }
3908
3909 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003910 // Ask the variable if it has a definition.
3911 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003912 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003913 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003914 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003915
Douglas Gregorb6998662010-01-19 19:34:47 +00003916 case Decl::FunctionTemplate: {
3917 const FunctionDecl *Def = 0;
3918 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003919 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003920 return clang_getNullCursor();
3921 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003922
Douglas Gregorb6998662010-01-19 19:34:47 +00003923 case Decl::ClassTemplate: {
3924 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003925 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003926 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003927 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003928 return clang_getNullCursor();
3929 }
3930
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003931 case Decl::Using:
3932 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003933 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003934
3935 case Decl::UsingShadow:
3936 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003937 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003938 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003939
3940 case Decl::ObjCMethod: {
3941 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3942 if (Method->isThisDeclarationADefinition())
3943 return C;
3944
3945 // Dig out the method definition in the associated
3946 // @implementation, if we have it.
3947 // FIXME: The ASTs should make finding the definition easier.
3948 if (ObjCInterfaceDecl *Class
3949 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3950 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3951 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3952 Method->isInstanceMethod()))
3953 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003954 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003955
3956 return clang_getNullCursor();
3957 }
3958
3959 case Decl::ObjCCategory:
3960 if (ObjCCategoryImplDecl *Impl
3961 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003962 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003963 return clang_getNullCursor();
3964
3965 case Decl::ObjCProtocol:
3966 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3967 return C;
3968 return clang_getNullCursor();
3969
3970 case Decl::ObjCInterface:
3971 // There are two notions of a "definition" for an Objective-C
3972 // class: the interface and its implementation. When we resolved a
3973 // reference to an Objective-C class, produce the @interface as
3974 // the definition; when we were provided with the interface,
3975 // produce the @implementation as the definition.
3976 if (WasReference) {
3977 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
3978 return C;
3979 } else if (ObjCImplementationDecl *Impl
3980 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003981 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003982 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003983
Douglas Gregorb6998662010-01-19 19:34:47 +00003984 case Decl::ObjCProperty:
3985 // FIXME: We don't really know where to find the
3986 // ObjCPropertyImplDecls that implement this property.
3987 return clang_getNullCursor();
3988
3989 case Decl::ObjCCompatibleAlias:
3990 if (ObjCInterfaceDecl *Class
3991 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
3992 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003993 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003994
Douglas Gregorb6998662010-01-19 19:34:47 +00003995 return clang_getNullCursor();
3996
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003997 case Decl::ObjCForwardProtocol:
3998 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003999 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004000
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004001 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004002 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004003 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004004
4005 case Decl::Friend:
4006 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004007 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004008 return clang_getNullCursor();
4009
4010 case Decl::FriendTemplate:
4011 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004012 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004013 return clang_getNullCursor();
4014 }
4015
4016 return clang_getNullCursor();
4017}
4018
4019unsigned clang_isCursorDefinition(CXCursor C) {
4020 if (!clang_isDeclaration(C.kind))
4021 return 0;
4022
4023 return clang_getCursorDefinition(C) == C;
4024}
4025
Douglas Gregor1a9d0502010-11-19 23:44:15 +00004026CXCursor clang_getCanonicalCursor(CXCursor C) {
4027 if (!clang_isDeclaration(C.kind))
4028 return C;
4029
4030 if (Decl *D = getCursorDecl(C))
4031 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4032
4033 return C;
4034}
4035
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004036unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004037 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004038 return 0;
4039
4040 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4041 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4042 return E->getNumDecls();
4043
4044 if (OverloadedTemplateStorage *S
4045 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4046 return S->size();
4047
4048 Decl *D = Storage.get<Decl*>();
4049 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00004050 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004051 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4052 return Classes->size();
4053 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4054 return Protocols->protocol_size();
4055
4056 return 0;
4057}
4058
4059CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004060 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004061 return clang_getNullCursor();
4062
4063 if (index >= clang_getNumOverloadedDecls(cursor))
4064 return clang_getNullCursor();
4065
Ted Kremeneka60ed472010-11-16 08:15:36 +00004066 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004067 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4068 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004069 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004070
4071 if (OverloadedTemplateStorage *S
4072 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004073 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004074
4075 Decl *D = Storage.get<Decl*>();
4076 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4077 // FIXME: This is, unfortunately, linear time.
4078 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4079 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004080 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004081 }
4082
4083 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004084 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004085
4086 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004087 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004088
4089 return clang_getNullCursor();
4090}
4091
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004092void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004093 const char **startBuf,
4094 const char **endBuf,
4095 unsigned *startLine,
4096 unsigned *startColumn,
4097 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004098 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004099 assert(getCursorDecl(C) && "CXCursor has null decl");
4100 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004101 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4102 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004103
Steve Naroff4ade6d62009-09-23 17:52:52 +00004104 SourceManager &SM = FD->getASTContext().getSourceManager();
4105 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4106 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4107 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4108 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4109 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4110 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4111}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004112
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004113void clang_enableStackTraces(void) {
4114 llvm::sys::PrintStackTraceOnErrorSignal();
4115}
4116
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004117void clang_executeOnThread(void (*fn)(void*), void *user_data,
4118 unsigned stack_size) {
4119 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4120}
4121
Ted Kremenekfb480492010-01-13 21:46:36 +00004122} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004123
Ted Kremenekfb480492010-01-13 21:46:36 +00004124//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004125// Token-based Operations.
4126//===----------------------------------------------------------------------===//
4127
4128/* CXToken layout:
4129 * int_data[0]: a CXTokenKind
4130 * int_data[1]: starting token location
4131 * int_data[2]: token length
4132 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004133 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004134 * otherwise unused.
4135 */
4136extern "C" {
4137
4138CXTokenKind clang_getTokenKind(CXToken CXTok) {
4139 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4140}
4141
4142CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4143 switch (clang_getTokenKind(CXTok)) {
4144 case CXToken_Identifier:
4145 case CXToken_Keyword:
4146 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004147 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4148 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004149
4150 case CXToken_Literal: {
4151 // We have stashed the starting pointer in the ptr_data field. Use it.
4152 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004153 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004154 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004155
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004156 case CXToken_Punctuation:
4157 case CXToken_Comment:
4158 break;
4159 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004160
4161 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004162 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004163 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004164 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004165 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004166
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004167 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4168 std::pair<FileID, unsigned> LocInfo
4169 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004170 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004171 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004172 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4173 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004174 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004175
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004176 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004177}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004178
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004179CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004180 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004181 if (!CXXUnit)
4182 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004183
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004184 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4185 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4186}
4187
4188CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004189 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004190 if (!CXXUnit)
4191 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004192
4193 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004194 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4195}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004196
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004197void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4198 CXToken **Tokens, unsigned *NumTokens) {
4199 if (Tokens)
4200 *Tokens = 0;
4201 if (NumTokens)
4202 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004203
Ted Kremeneka60ed472010-11-16 08:15:36 +00004204 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004205 if (!CXXUnit || !Tokens || !NumTokens)
4206 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004207
Douglas Gregorbdf60622010-03-05 21:16:25 +00004208 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4209
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004210 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004211 if (R.isInvalid())
4212 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004213
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004214 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4215 std::pair<FileID, unsigned> BeginLocInfo
4216 = SourceMgr.getDecomposedLoc(R.getBegin());
4217 std::pair<FileID, unsigned> EndLocInfo
4218 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004219
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004220 // Cannot tokenize across files.
4221 if (BeginLocInfo.first != EndLocInfo.first)
4222 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004223
4224 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004225 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004226 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004227 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004228 if (Invalid)
4229 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004230
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004231 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4232 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004233 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004234 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004235
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004236 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004237 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004238 llvm::SmallVector<CXToken, 32> CXTokens;
4239 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004240 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004241 do {
4242 // Lex the next token
4243 Lex.LexFromRawLexer(Tok);
4244 if (Tok.is(tok::eof))
4245 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004246
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004247 // Initialize the CXToken.
4248 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004249
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004250 // - Common fields
4251 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4252 CXTok.int_data[2] = Tok.getLength();
4253 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004254
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004255 // - Kind-specific fields
4256 if (Tok.isLiteral()) {
4257 CXTok.int_data[0] = CXToken_Literal;
4258 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004259 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004260 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004261 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004262 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004263
David Chisnall096428b2010-10-13 21:44:48 +00004264 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004265 CXTok.int_data[0] = CXToken_Keyword;
4266 }
4267 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004268 CXTok.int_data[0] = Tok.is(tok::identifier)
4269 ? CXToken_Identifier
4270 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004271 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004272 CXTok.ptr_data = II;
4273 } else if (Tok.is(tok::comment)) {
4274 CXTok.int_data[0] = CXToken_Comment;
4275 CXTok.ptr_data = 0;
4276 } else {
4277 CXTok.int_data[0] = CXToken_Punctuation;
4278 CXTok.ptr_data = 0;
4279 }
4280 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004281 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004282 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004283
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004284 if (CXTokens.empty())
4285 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004286
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004287 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4288 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4289 *NumTokens = CXTokens.size();
4290}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004291
Ted Kremenek6db61092010-05-05 00:55:15 +00004292void clang_disposeTokens(CXTranslationUnit TU,
4293 CXToken *Tokens, unsigned NumTokens) {
4294 free(Tokens);
4295}
4296
4297} // end: extern "C"
4298
4299//===----------------------------------------------------------------------===//
4300// Token annotation APIs.
4301//===----------------------------------------------------------------------===//
4302
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004303typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004304static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4305 CXCursor parent,
4306 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004307namespace {
4308class AnnotateTokensWorker {
4309 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004310 CXToken *Tokens;
4311 CXCursor *Cursors;
4312 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004313 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004314 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004315 CursorVisitor AnnotateVis;
4316 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004317 bool HasContextSensitiveKeywords;
4318
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004319 bool MoreTokens() const { return TokIdx < NumTokens; }
4320 unsigned NextToken() const { return TokIdx; }
4321 void AdvanceToken() { ++TokIdx; }
4322 SourceLocation GetTokenLoc(unsigned tokI) {
4323 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4324 }
4325
Ted Kremenek6db61092010-05-05 00:55:15 +00004326public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004327 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004328 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004329 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004330 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004331 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004332 AnnotateVis(tu,
4333 AnnotateTokensVisitor, this,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00004334 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004335 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4336 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004337
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004338 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004339 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004340 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004341 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004342 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004343 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004344
4345 /// \brief Determine whether the annotator saw any cursors that have
4346 /// context-sensitive keywords.
4347 bool hasContextSensitiveKeywords() const {
4348 return HasContextSensitiveKeywords;
4349 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004350};
4351}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004352
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004353void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4354 // Walk the AST within the region of interest, annotating tokens
4355 // along the way.
4356 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004357
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004358 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4359 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004360 if (Pos != Annotated.end() &&
4361 (clang_isInvalid(Cursors[I].kind) ||
4362 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004363 Cursors[I] = Pos->second;
4364 }
4365
4366 // Finish up annotating any tokens left.
4367 if (!MoreTokens())
4368 return;
4369
4370 const CXCursor &C = clang_getNullCursor();
4371 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4372 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4373 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004374 }
4375}
4376
Ted Kremenek6db61092010-05-05 00:55:15 +00004377enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004378AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004379 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004380 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004381 if (cursorRange.isInvalid())
4382 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004383
4384 if (!HasContextSensitiveKeywords) {
4385 // Objective-C properties can have context-sensitive keywords.
4386 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4387 if (ObjCPropertyDecl *Property
4388 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4389 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4390 }
4391 // Objective-C methods can have context-sensitive keywords.
4392 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4393 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4394 if (ObjCMethodDecl *Method
4395 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4396 if (Method->getObjCDeclQualifier())
4397 HasContextSensitiveKeywords = true;
4398 else {
4399 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4400 PEnd = Method->param_end();
4401 P != PEnd; ++P) {
4402 if ((*P)->getObjCDeclQualifier()) {
4403 HasContextSensitiveKeywords = true;
4404 break;
4405 }
4406 }
4407 }
4408 }
4409 }
4410 // C++ methods can have context-sensitive keywords.
4411 else if (cursor.kind == CXCursor_CXXMethod) {
4412 if (CXXMethodDecl *Method
4413 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4414 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4415 HasContextSensitiveKeywords = true;
4416 }
4417 }
4418 // C++ classes can have context-sensitive keywords.
4419 else if (cursor.kind == CXCursor_StructDecl ||
4420 cursor.kind == CXCursor_ClassDecl ||
4421 cursor.kind == CXCursor_ClassTemplate ||
4422 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4423 if (Decl *D = getCursorDecl(cursor))
4424 if (D->hasAttr<FinalAttr>())
4425 HasContextSensitiveKeywords = true;
4426 }
4427 }
4428
Douglas Gregor4419b672010-10-21 06:10:04 +00004429 if (clang_isPreprocessing(cursor.kind)) {
4430 // For macro instantiations, just note where the beginning of the macro
4431 // instantiation occurs.
4432 if (cursor.kind == CXCursor_MacroInstantiation) {
4433 Annotated[Loc.int_data] = cursor;
4434 return CXChildVisit_Recurse;
4435 }
4436
Douglas Gregor4419b672010-10-21 06:10:04 +00004437 // Items in the preprocessing record are kept separate from items in
4438 // declarations, so we keep a separate token index.
4439 unsigned SavedTokIdx = TokIdx;
4440 TokIdx = PreprocessingTokIdx;
4441
4442 // Skip tokens up until we catch up to the beginning of the preprocessing
4443 // entry.
4444 while (MoreTokens()) {
4445 const unsigned I = NextToken();
4446 SourceLocation TokLoc = GetTokenLoc(I);
4447 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4448 case RangeBefore:
4449 AdvanceToken();
4450 continue;
4451 case RangeAfter:
4452 case RangeOverlap:
4453 break;
4454 }
4455 break;
4456 }
4457
4458 // Look at all of the tokens within this range.
4459 while (MoreTokens()) {
4460 const unsigned I = NextToken();
4461 SourceLocation TokLoc = GetTokenLoc(I);
4462 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4463 case RangeBefore:
4464 assert(0 && "Infeasible");
4465 case RangeAfter:
4466 break;
4467 case RangeOverlap:
4468 Cursors[I] = cursor;
4469 AdvanceToken();
4470 continue;
4471 }
4472 break;
4473 }
4474
4475 // Save the preprocessing token index; restore the non-preprocessing
4476 // token index.
4477 PreprocessingTokIdx = TokIdx;
4478 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004479 return CXChildVisit_Recurse;
4480 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004481
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004482 if (cursorRange.isInvalid())
4483 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004484
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004485 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4486
Ted Kremeneka333c662010-05-12 05:29:33 +00004487 // Adjust the annotated range based specific declarations.
4488 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4489 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004490 Decl *D = cxcursor::getCursorDecl(cursor);
4491 // Don't visit synthesized ObjC methods, since they have no syntatic
4492 // representation in the source.
4493 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4494 if (MD->isSynthesized())
4495 return CXChildVisit_Continue;
4496 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004497
4498 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004499 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004500 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4501 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4502 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4503 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4504 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004505 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004506
4507 if (StartLoc.isValid() && L.isValid() &&
4508 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4509 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004510 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004511
Ted Kremenek3f404602010-08-14 01:14:06 +00004512 // If the location of the cursor occurs within a macro instantiation, record
4513 // the spelling location of the cursor in our annotation map. We can then
4514 // paper over the token labelings during a post-processing step to try and
4515 // get cursor mappings for tokens that are the *arguments* of a macro
4516 // instantiation.
4517 if (L.isMacroID()) {
4518 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4519 // Only invalidate the old annotation if it isn't part of a preprocessing
4520 // directive. Here we assume that the default construction of CXCursor
4521 // results in CXCursor.kind being an initialized value (i.e., 0). If
4522 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004523
Ted Kremenek3f404602010-08-14 01:14:06 +00004524 CXCursor &oldC = Annotated[rawEncoding];
4525 if (!clang_isPreprocessing(oldC.kind))
4526 oldC = cursor;
4527 }
4528
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004529 const enum CXCursorKind K = clang_getCursorKind(parent);
4530 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004531 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4532 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004533
4534 while (MoreTokens()) {
4535 const unsigned I = NextToken();
4536 SourceLocation TokLoc = GetTokenLoc(I);
4537 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4538 case RangeBefore:
4539 Cursors[I] = updateC;
4540 AdvanceToken();
4541 continue;
4542 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004543 case RangeOverlap:
4544 break;
4545 }
4546 break;
4547 }
4548
4549 // Visit children to get their cursor information.
4550 const unsigned BeforeChildren = NextToken();
4551 VisitChildren(cursor);
4552 const unsigned AfterChildren = NextToken();
4553
4554 // Adjust 'Last' to the last token within the extent of the cursor.
4555 while (MoreTokens()) {
4556 const unsigned I = NextToken();
4557 SourceLocation TokLoc = GetTokenLoc(I);
4558 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4559 case RangeBefore:
4560 assert(0 && "Infeasible");
4561 case RangeAfter:
4562 break;
4563 case RangeOverlap:
4564 Cursors[I] = updateC;
4565 AdvanceToken();
4566 continue;
4567 }
4568 break;
4569 }
4570 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004571
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004572 // Scan the tokens that are at the beginning of the cursor, but are not
4573 // capture by the child cursors.
4574
4575 // For AST elements within macros, rely on a post-annotate pass to
4576 // to correctly annotate the tokens with cursors. Otherwise we can
4577 // get confusing results of having tokens that map to cursors that really
4578 // are expanded by an instantiation.
4579 if (L.isMacroID())
4580 cursor = clang_getNullCursor();
4581
4582 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4583 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4584 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004585
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004586 Cursors[I] = cursor;
4587 }
4588 // Scan the tokens that are at the end of the cursor, but are not captured
4589 // but the child cursors.
4590 for (unsigned I = AfterChildren; I != Last; ++I)
4591 Cursors[I] = cursor;
4592
4593 TokIdx = Last;
4594 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004595}
4596
Ted Kremenek6db61092010-05-05 00:55:15 +00004597static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4598 CXCursor parent,
4599 CXClientData client_data) {
4600 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4601}
4602
Ted Kremenek6628a612011-03-18 22:51:30 +00004603namespace {
4604 struct clang_annotateTokens_Data {
4605 CXTranslationUnit TU;
4606 ASTUnit *CXXUnit;
4607 CXToken *Tokens;
4608 unsigned NumTokens;
4609 CXCursor *Cursors;
4610 };
4611}
4612
Ted Kremenekab979612010-11-11 08:05:23 +00004613// This gets run a separate thread to avoid stack blowout.
Ted Kremenek6628a612011-03-18 22:51:30 +00004614static void clang_annotateTokensImpl(void *UserData) {
4615 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4616 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4617 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4618 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4619 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4620
4621 // Determine the region of interest, which contains all of the tokens.
4622 SourceRange RegionOfInterest;
4623 RegionOfInterest.setBegin(
4624 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4625 RegionOfInterest.setEnd(
4626 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4627 Tokens[NumTokens-1])));
4628
4629 // A mapping from the source locations found when re-lexing or traversing the
4630 // region of interest to the corresponding cursors.
4631 AnnotateTokensData Annotated;
4632
4633 // Relex the tokens within the source range to look for preprocessing
4634 // directives.
4635 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4636 std::pair<FileID, unsigned> BeginLocInfo
4637 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4638 std::pair<FileID, unsigned> EndLocInfo
4639 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4640
4641 llvm::StringRef Buffer;
4642 bool Invalid = false;
4643 if (BeginLocInfo.first == EndLocInfo.first &&
4644 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4645 !Invalid) {
4646 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4647 CXXUnit->getASTContext().getLangOptions(),
4648 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4649 Buffer.end());
4650 Lex.SetCommentRetentionState(true);
4651
4652 // Lex tokens in raw mode until we hit the end of the range, to avoid
4653 // entering #includes or expanding macros.
4654 while (true) {
4655 Token Tok;
4656 Lex.LexFromRawLexer(Tok);
4657
4658 reprocess:
4659 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4660 // We have found a preprocessing directive. Gobble it up so that we
4661 // don't see it while preprocessing these tokens later, but keep track
4662 // of all of the token locations inside this preprocessing directive so
4663 // that we can annotate them appropriately.
4664 //
4665 // FIXME: Some simple tests here could identify macro definitions and
4666 // #undefs, to provide specific cursor kinds for those.
4667 llvm::SmallVector<SourceLocation, 32> Locations;
4668 do {
4669 Locations.push_back(Tok.getLocation());
4670 Lex.LexFromRawLexer(Tok);
4671 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4672
4673 using namespace cxcursor;
4674 CXCursor Cursor
4675 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4676 Locations.back()),
4677 TU);
4678 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4679 Annotated[Locations[I].getRawEncoding()] = Cursor;
4680 }
4681
4682 if (Tok.isAtStartOfLine())
4683 goto reprocess;
4684
4685 continue;
4686 }
4687
4688 if (Tok.is(tok::eof))
4689 break;
4690 }
4691 }
4692
4693 // Annotate all of the source locations in the region of interest that map to
4694 // a specific cursor.
4695 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4696 TU, RegionOfInterest);
4697
4698 // FIXME: We use a ridiculous stack size here because the data-recursion
4699 // algorithm uses a large stack frame than the non-data recursive version,
4700 // and AnnotationTokensWorker currently transforms the data-recursion
4701 // algorithm back into a traditional recursion by explicitly calling
4702 // VisitChildren(). We will need to remove this explicit recursive call.
4703 W.AnnotateTokens();
4704
4705 // If we ran into any entities that involve context-sensitive keywords,
4706 // take another pass through the tokens to mark them as such.
4707 if (W.hasContextSensitiveKeywords()) {
4708 for (unsigned I = 0; I != NumTokens; ++I) {
4709 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4710 continue;
4711
4712 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4713 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4714 if (ObjCPropertyDecl *Property
4715 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4716 if (Property->getPropertyAttributesAsWritten() != 0 &&
4717 llvm::StringSwitch<bool>(II->getName())
4718 .Case("readonly", true)
4719 .Case("assign", true)
4720 .Case("readwrite", true)
4721 .Case("retain", true)
4722 .Case("copy", true)
4723 .Case("nonatomic", true)
4724 .Case("atomic", true)
4725 .Case("getter", true)
4726 .Case("setter", true)
4727 .Default(false))
4728 Tokens[I].int_data[0] = CXToken_Keyword;
4729 }
4730 continue;
4731 }
4732
4733 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4734 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4735 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4736 if (llvm::StringSwitch<bool>(II->getName())
4737 .Case("in", true)
4738 .Case("out", true)
4739 .Case("inout", true)
4740 .Case("oneway", true)
4741 .Case("bycopy", true)
4742 .Case("byref", true)
4743 .Default(false))
4744 Tokens[I].int_data[0] = CXToken_Keyword;
4745 continue;
4746 }
4747
4748 if (Cursors[I].kind == CXCursor_CXXMethod) {
4749 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4750 if (CXXMethodDecl *Method
4751 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4752 if ((Method->hasAttr<FinalAttr>() ||
4753 Method->hasAttr<OverrideAttr>()) &&
4754 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4755 llvm::StringSwitch<bool>(II->getName())
4756 .Case("final", true)
4757 .Case("override", true)
4758 .Default(false))
4759 Tokens[I].int_data[0] = CXToken_Keyword;
4760 }
4761 continue;
4762 }
4763
4764 if (Cursors[I].kind == CXCursor_ClassDecl ||
4765 Cursors[I].kind == CXCursor_StructDecl ||
4766 Cursors[I].kind == CXCursor_ClassTemplate) {
4767 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4768 if (II->getName() == "final") {
4769 // We have to be careful with 'final', since it could be the name
4770 // of a member class rather than the context-sensitive keyword.
4771 // So, check whether the cursor associated with this
4772 Decl *D = getCursorDecl(Cursors[I]);
4773 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4774 if ((Record->hasAttr<FinalAttr>()) &&
4775 Record->getIdentifier() != II)
4776 Tokens[I].int_data[0] = CXToken_Keyword;
4777 } else if (ClassTemplateDecl *ClassTemplate
4778 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4779 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4780 if ((Record->hasAttr<FinalAttr>()) &&
4781 Record->getIdentifier() != II)
4782 Tokens[I].int_data[0] = CXToken_Keyword;
4783 }
4784 }
4785 continue;
4786 }
4787 }
4788 }
Ted Kremenekab979612010-11-11 08:05:23 +00004789}
4790
Ted Kremenek6db61092010-05-05 00:55:15 +00004791extern "C" {
4792
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004793void clang_annotateTokens(CXTranslationUnit TU,
4794 CXToken *Tokens, unsigned NumTokens,
4795 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004796
4797 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004798 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004799
Douglas Gregor4419b672010-10-21 06:10:04 +00004800 // Any token we don't specifically annotate will have a NULL cursor.
4801 CXCursor C = clang_getNullCursor();
4802 for (unsigned I = 0; I != NumTokens; ++I)
4803 Cursors[I] = C;
4804
Ted Kremeneka60ed472010-11-16 08:15:36 +00004805 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004806 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004807 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004808
Douglas Gregorbdf60622010-03-05 21:16:25 +00004809 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek6628a612011-03-18 22:51:30 +00004810
4811 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekab979612010-11-11 08:05:23 +00004812 llvm::CrashRecoveryContext CRC;
Ted Kremenek6628a612011-03-18 22:51:30 +00004813 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004814 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004815 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4816 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004817}
Ted Kremenek6628a612011-03-18 22:51:30 +00004818
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004819} // end: extern "C"
4820
4821//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004822// Operations for querying linkage of a cursor.
4823//===----------------------------------------------------------------------===//
4824
4825extern "C" {
4826CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004827 if (!clang_isDeclaration(cursor.kind))
4828 return CXLinkage_Invalid;
4829
Ted Kremenek16b42592010-03-03 06:36:57 +00004830 Decl *D = cxcursor::getCursorDecl(cursor);
4831 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4832 switch (ND->getLinkage()) {
4833 case NoLinkage: return CXLinkage_NoLinkage;
4834 case InternalLinkage: return CXLinkage_Internal;
4835 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4836 case ExternalLinkage: return CXLinkage_External;
4837 };
4838
4839 return CXLinkage_Invalid;
4840}
4841} // end: extern "C"
4842
4843//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004844// Operations for querying language of a cursor.
4845//===----------------------------------------------------------------------===//
4846
4847static CXLanguageKind getDeclLanguage(const Decl *D) {
4848 switch (D->getKind()) {
4849 default:
4850 break;
4851 case Decl::ImplicitParam:
4852 case Decl::ObjCAtDefsField:
4853 case Decl::ObjCCategory:
4854 case Decl::ObjCCategoryImpl:
4855 case Decl::ObjCClass:
4856 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004857 case Decl::ObjCForwardProtocol:
4858 case Decl::ObjCImplementation:
4859 case Decl::ObjCInterface:
4860 case Decl::ObjCIvar:
4861 case Decl::ObjCMethod:
4862 case Decl::ObjCProperty:
4863 case Decl::ObjCPropertyImpl:
4864 case Decl::ObjCProtocol:
4865 return CXLanguage_ObjC;
4866 case Decl::CXXConstructor:
4867 case Decl::CXXConversion:
4868 case Decl::CXXDestructor:
4869 case Decl::CXXMethod:
4870 case Decl::CXXRecord:
4871 case Decl::ClassTemplate:
4872 case Decl::ClassTemplatePartialSpecialization:
4873 case Decl::ClassTemplateSpecialization:
4874 case Decl::Friend:
4875 case Decl::FriendTemplate:
4876 case Decl::FunctionTemplate:
4877 case Decl::LinkageSpec:
4878 case Decl::Namespace:
4879 case Decl::NamespaceAlias:
4880 case Decl::NonTypeTemplateParm:
4881 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004882 case Decl::TemplateTemplateParm:
4883 case Decl::TemplateTypeParm:
4884 case Decl::UnresolvedUsingTypename:
4885 case Decl::UnresolvedUsingValue:
4886 case Decl::Using:
4887 case Decl::UsingDirective:
4888 case Decl::UsingShadow:
4889 return CXLanguage_CPlusPlus;
4890 }
4891
4892 return CXLanguage_C;
4893}
4894
4895extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004896
4897enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4898 if (clang_isDeclaration(cursor.kind))
4899 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004900 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregor58ddb602010-08-23 23:00:57 +00004901 return CXAvailability_Available;
4902
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004903 switch (D->getAvailability()) {
4904 case AR_Available:
4905 case AR_NotYetIntroduced:
4906 return CXAvailability_Available;
4907
4908 case AR_Deprecated:
Douglas Gregor58ddb602010-08-23 23:00:57 +00004909 return CXAvailability_Deprecated;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004910
4911 case AR_Unavailable:
4912 return CXAvailability_NotAvailable;
4913 }
Douglas Gregor58ddb602010-08-23 23:00:57 +00004914 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004915
Douglas Gregor58ddb602010-08-23 23:00:57 +00004916 return CXAvailability_Available;
4917}
4918
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004919CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4920 if (clang_isDeclaration(cursor.kind))
4921 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4922
4923 return CXLanguage_Invalid;
4924}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004925
4926 /// \brief If the given cursor is the "templated" declaration
4927 /// descibing a class or function template, return the class or
4928 /// function template.
4929static Decl *maybeGetTemplateCursor(Decl *D) {
4930 if (!D)
4931 return 0;
4932
4933 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4934 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4935 return FunTmpl;
4936
4937 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4938 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4939 return ClassTmpl;
4940
4941 return D;
4942}
4943
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004944CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4945 if (clang_isDeclaration(cursor.kind)) {
4946 if (Decl *D = getCursorDecl(cursor)) {
4947 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004948 if (!DC)
4949 return clang_getNullCursor();
4950
4951 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4952 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004953 }
4954 }
4955
4956 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4957 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004958 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004959 }
4960
4961 return clang_getNullCursor();
4962}
4963
4964CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4965 if (clang_isDeclaration(cursor.kind)) {
4966 if (Decl *D = getCursorDecl(cursor)) {
4967 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004968 if (!DC)
4969 return clang_getNullCursor();
4970
4971 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4972 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004973 }
4974 }
4975
4976 // FIXME: Note that we can't easily compute the lexical context of a
4977 // statement or expression, so we return nothing.
4978 return clang_getNullCursor();
4979}
4980
Douglas Gregor9f592342010-10-01 20:25:15 +00004981static void CollectOverriddenMethods(DeclContext *Ctx,
4982 ObjCMethodDecl *Method,
4983 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
4984 if (!Ctx)
4985 return;
4986
4987 // If we have a class or category implementation, jump straight to the
4988 // interface.
4989 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
4990 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
4991
4992 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
4993 if (!Container)
4994 return;
4995
4996 // Check whether we have a matching method at this level.
4997 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
4998 Method->isInstanceMethod()))
4999 if (Method != Overridden) {
5000 // We found an override at this level; there is no need to look
5001 // into other protocols or categories.
5002 Methods.push_back(Overridden);
5003 return;
5004 }
5005
5006 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5007 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5008 PEnd = Protocol->protocol_end();
5009 P != PEnd; ++P)
5010 CollectOverriddenMethods(*P, Method, Methods);
5011 }
5012
5013 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5014 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5015 PEnd = Category->protocol_end();
5016 P != PEnd; ++P)
5017 CollectOverriddenMethods(*P, Method, Methods);
5018 }
5019
5020 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5021 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5022 PEnd = Interface->protocol_end();
5023 P != PEnd; ++P)
5024 CollectOverriddenMethods(*P, Method, Methods);
5025
5026 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5027 Category; Category = Category->getNextClassCategory())
5028 CollectOverriddenMethods(Category, Method, Methods);
5029
5030 // We only look into the superclass if we haven't found anything yet.
5031 if (Methods.empty())
5032 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5033 return CollectOverriddenMethods(Super, Method, Methods);
5034 }
5035}
5036
5037void clang_getOverriddenCursors(CXCursor cursor,
5038 CXCursor **overridden,
5039 unsigned *num_overridden) {
5040 if (overridden)
5041 *overridden = 0;
5042 if (num_overridden)
5043 *num_overridden = 0;
5044 if (!overridden || !num_overridden)
5045 return;
5046
5047 if (!clang_isDeclaration(cursor.kind))
5048 return;
5049
5050 Decl *D = getCursorDecl(cursor);
5051 if (!D)
5052 return;
5053
5054 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00005055 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00005056 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5057 *num_overridden = CXXMethod->size_overridden_methods();
5058 if (!*num_overridden)
5059 return;
5060
5061 *overridden = new CXCursor [*num_overridden];
5062 unsigned I = 0;
5063 for (CXXMethodDecl::method_iterator
5064 M = CXXMethod->begin_overridden_methods(),
5065 MEnd = CXXMethod->end_overridden_methods();
5066 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005067 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005068 return;
5069 }
5070
5071 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5072 if (!Method)
5073 return;
5074
5075 // Handle Objective-C methods.
5076 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5077 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5078
5079 if (Methods.empty())
5080 return;
5081
5082 *num_overridden = Methods.size();
5083 *overridden = new CXCursor [Methods.size()];
5084 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005085 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005086}
5087
5088void clang_disposeOverriddenCursors(CXCursor *overridden) {
5089 delete [] overridden;
5090}
5091
Douglas Gregorecdcb882010-10-20 22:00:55 +00005092CXFile clang_getIncludedFile(CXCursor cursor) {
5093 if (cursor.kind != CXCursor_InclusionDirective)
5094 return 0;
5095
5096 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5097 return (void *)ID->getFile();
5098}
5099
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005100} // end: extern "C"
5101
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005102
5103//===----------------------------------------------------------------------===//
5104// C++ AST instrospection.
5105//===----------------------------------------------------------------------===//
5106
5107extern "C" {
5108unsigned clang_CXXMethod_isStatic(CXCursor C) {
5109 if (!clang_isDeclaration(C.kind))
5110 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005111
5112 CXXMethodDecl *Method = 0;
5113 Decl *D = cxcursor::getCursorDecl(C);
5114 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5115 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5116 else
5117 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5118 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005119}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005120
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005121} // end: extern "C"
5122
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005123//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005124// Attribute introspection.
5125//===----------------------------------------------------------------------===//
5126
5127extern "C" {
5128CXType clang_getIBOutletCollectionType(CXCursor C) {
5129 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005130 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005131
5132 IBOutletCollectionAttr *A =
5133 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5134
Douglas Gregor841b2382011-03-06 18:55:32 +00005135 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005136}
5137} // end: extern "C"
5138
5139//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005140// Misc. utility functions.
5141//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005142
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005143/// Default to using an 8 MB stack size on "safety" threads.
5144static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005145
5146namespace clang {
5147
5148bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005149 void (*Fn)(void*), void *UserData,
5150 unsigned Size) {
5151 if (!Size)
5152 Size = GetSafetyThreadStackSize();
5153 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005154 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5155 return CRC.RunSafely(Fn, UserData);
5156}
5157
5158unsigned GetSafetyThreadStackSize() {
5159 return SafetyStackThreadSize;
5160}
5161
5162void SetSafetyThreadStackSize(unsigned Value) {
5163 SafetyStackThreadSize = Value;
5164}
5165
5166}
5167
Ted Kremenek04bb7162010-01-22 22:44:15 +00005168extern "C" {
5169
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005170CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005171 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005172}
5173
5174} // end: extern "C"