blob: 0aba04a48c6f3f3cff370939c0c55e13a38e37a9 [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);
Douglas Gregor06d9b1a2011-04-14 21:41:34 +0000497 if (!D)
498 return false;
499
Ted Kremenek539311e2010-02-18 18:47:01 +0000500 return VisitAttributes(D) || Visit(D);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000501 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000502
Douglas Gregor06d9b1a2011-04-14 21:41:34 +0000503 if (clang_isStatement(Cursor.kind)) {
504 if (Stmt *S = getCursorStmt(Cursor))
505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
511 if (Expr *E = getCursorExpr(Cursor))
512 return Visit(E);
513
514 return false;
515 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000516
Douglas Gregorb1373d02010-01-20 20:59:29 +0000517 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000518 CXTranslationUnit tu = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
529 if (Visit(MakeCXCursor(*TL, tu), true))
530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
Douglas Gregor7b691f332010-01-20 21:13:59 +0000534 return true;
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000535 continue;
Douglas Gregor7b691f332010-01-20 21:13:59 +0000536 }
Bob Wilson3178cb62010-03-19 03:57:57 +0000537
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
540 // FIXME: Once we have the ability to deserialize a preprocessing record,
541 // do so.
542 PreprocessingRecord::iterator E, EEnd;
543 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
544 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
545 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
546 return true;
547
548 continue;
549 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000550
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000551 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
552 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
553 return true;
554
555 continue;
556 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000557
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000558 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
559 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
560 return true;
561
562 continue;
563 }
Douglas Gregorecdcb882010-10-20 22:00:55 +0000564 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000565 }
566 }
Douglas Gregor04a9eb32011-03-16 23:23:30 +0000567
Douglas Gregor7b691f332010-01-20 21:13:59 +0000568 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000569 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000570
Douglas Gregorc314aa42011-03-02 19:17:03 +0000571 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
572 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
573 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
574 return Visit(BaseTSInfo->getTypeLoc());
575 }
576 }
577 }
578
Douglas Gregorb1373d02010-01-20 20:59:29 +0000579 // Nothing to visit at the moment.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000580 return false;
581}
582
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000583bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
John McCallfc929202010-06-04 22:33:30 +0000584 if (Visit(B->getSignatureAsWritten()->getTypeLoc()))
585 return true;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000586
Ted Kremenek664cffd2010-07-22 11:30:19 +0000587 if (Stmt *Body = B->getBody())
588 return Visit(MakeCXCursor(Body, StmtParent, TU));
589
590 return false;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000591}
592
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000593llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
594 if (RegionOfInterest.isValid()) {
Douglas Gregor66537982010-11-17 17:14:07 +0000595 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000596 if (Range.isInvalid())
597 return llvm::Optional<bool>();
Douglas Gregor66537982010-11-17 17:14:07 +0000598
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000599 switch (CompareRegionOfInterest(Range)) {
600 case RangeBefore:
601 // This declaration comes before the region of interest; skip it.
602 return llvm::Optional<bool>();
603
604 case RangeAfter:
605 // This declaration comes after the region of interest; we're done.
606 return false;
607
608 case RangeOverlap:
609 // This declaration overlaps the region of interest; visit it.
610 break;
611 }
612 }
613 return true;
614}
615
616bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
617 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
618
619 // FIXME: Eventually remove. This part of a hack to support proper
620 // iteration over all Decls contained lexically within an ObjC container.
621 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
622 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
623
624 for ( ; I != E; ++I) {
Ted Kremenek23173d72010-05-18 21:09:07 +0000625 Decl *D = *I;
626 if (D->getLexicalDeclContext() != DC)
627 continue;
Ted Kremenek23173d72010-05-18 21:09:07 +0000628 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000629 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
630 if (!V.hasValue())
631 continue;
632 if (!V.getValue())
633 return false;
Daniel Dunbard52864b2010-02-14 10:02:57 +0000634 if (Visit(Cursor, true))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000635 return true;
636 }
Douglas Gregorb1373d02010-01-20 20:59:29 +0000637 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000638}
639
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000640bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
641 llvm_unreachable("Translation units are visited directly by Visit()");
642 return false;
643}
644
645bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
646 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
647 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000648
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000649 return false;
650}
651
652bool CursorVisitor::VisitTagDecl(TagDecl *D) {
653 return VisitDeclContext(D);
654}
655
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000656bool CursorVisitor::VisitClassTemplateSpecializationDecl(
657 ClassTemplateSpecializationDecl *D) {
658 bool ShouldVisitBody = false;
659 switch (D->getSpecializationKind()) {
660 case TSK_Undeclared:
661 case TSK_ImplicitInstantiation:
662 // Nothing to visit
663 return false;
664
665 case TSK_ExplicitInstantiationDeclaration:
666 case TSK_ExplicitInstantiationDefinition:
667 break;
668
669 case TSK_ExplicitSpecialization:
670 ShouldVisitBody = true;
671 break;
672 }
673
674 // Visit the template arguments used in the specialization.
675 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
676 TypeLoc TL = SpecType->getTypeLoc();
677 if (TemplateSpecializationTypeLoc *TSTLoc
678 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
679 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
680 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
681 return true;
682 }
683 }
684
685 if (ShouldVisitBody && VisitCXXRecordDecl(D))
686 return true;
687
688 return false;
689}
690
Douglas Gregor74dbe642010-08-31 19:31:58 +0000691bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
692 ClassTemplatePartialSpecializationDecl *D) {
693 // FIXME: Visit the "outer" template parameter lists on the TagDecl
694 // before visiting these template parameters.
695 if (VisitTemplateParameters(D->getTemplateParameters()))
696 return true;
697
698 // Visit the partial specialization arguments.
699 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
700 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
702 return true;
703
704 return VisitCXXRecordDecl(D);
705}
706
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000707bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor84b51d72010-09-01 20:16:53 +0000708 // Visit the default argument.
709 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
710 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
711 if (Visit(DefArg->getTypeLoc()))
712 return true;
713
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000714 return false;
715}
716
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000717bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
718 if (Expr *Init = D->getInitExpr())
719 return Visit(MakeCXCursor(Init, StmtParent, TU));
720 return false;
721}
722
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000723bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
724 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
725 if (Visit(TSInfo->getTypeLoc()))
726 return true;
727
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000728 // Visit the nested-name-specifier, if present.
729 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
730 if (VisitNestedNameSpecifierLoc(QualifierLoc))
731 return true;
732
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000733 return false;
734}
735
Douglas Gregora67e03f2010-09-09 21:42:20 +0000736/// \brief Compare two base or member initializers based on their source order.
Sean Huntcbb67482011-01-08 20:30:50 +0000737static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
738 CXXCtorInitializer const * const *X
739 = static_cast<CXXCtorInitializer const * const *>(Xp);
740 CXXCtorInitializer const * const *Y
741 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000742
743 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
744 return -1;
745 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
746 return 1;
747 else
748 return 0;
749}
750
Douglas Gregorb1373d02010-01-20 20:59:29 +0000751bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor01829d32010-08-31 14:41:23 +0000752 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
753 // Visit the function declaration's syntactic components in the order
754 // written. This requires a bit of work.
Abramo Bagnara723df242010-12-14 22:11:44 +0000755 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor01829d32010-08-31 14:41:23 +0000756 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
757
758 // If we have a function declared directly (without the use of a typedef),
759 // visit just the return type. Otherwise, just visit the function's type
760 // now.
761 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
762 (!FTL && Visit(TL)))
763 return true;
764
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000765 // Visit the nested-name-specifier, if present.
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000766 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000768 return true;
Douglas Gregor01829d32010-08-31 14:41:23 +0000769
770 // Visit the declaration name.
771 if (VisitDeclarationNameInfo(ND->getNameInfo()))
772 return true;
773
774 // FIXME: Visit explicitly-specified template arguments!
775
776 // Visit the function parameters, if we have a function type.
777 if (FTL && VisitFunctionTypeLoc(*FTL, true))
778 return true;
779
780 // FIXME: Attributes?
781 }
782
Douglas Gregora67e03f2010-09-09 21:42:20 +0000783 if (ND->isThisDeclarationADefinition()) {
784 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
785 // Find the initializers that were written in the source.
Sean Huntcbb67482011-01-08 20:30:50 +0000786 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregora67e03f2010-09-09 21:42:20 +0000787 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
788 IEnd = Constructor->init_end();
789 I != IEnd; ++I) {
790 if (!(*I)->isWritten())
791 continue;
792
793 WrittenInits.push_back(*I);
794 }
795
796 // Sort the initializers in source order
797 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Sean Huntcbb67482011-01-08 20:30:50 +0000798 &CompareCXXCtorInitializers);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000799
800 // Visit the initializers in source order
801 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Sean Huntcbb67482011-01-08 20:30:50 +0000802 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichet00eb3f92010-12-04 09:14:42 +0000803 if (Init->isAnyMemberInitializer()) {
804 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregora67e03f2010-09-09 21:42:20 +0000805 Init->getMemberLocation(), TU)))
806 return true;
807 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
808 if (Visit(BaseInfo->getTypeLoc()))
809 return true;
810 }
811
812 // Visit the initializer value.
813 if (Expr *Initializer = Init->getInit())
814 if (Visit(MakeCXCursor(Initializer, ND, TU)))
815 return true;
816 }
817 }
818
819 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
820 return true;
821 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000822
Douglas Gregorb1373d02010-01-20 20:59:29 +0000823 return false;
824}
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000825
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000826bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
827 if (VisitDeclaratorDecl(D))
828 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000829
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000830 if (Expr *BitWidth = D->getBitWidth())
831 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000832
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000833 return false;
834}
835
836bool CursorVisitor::VisitVarDecl(VarDecl *D) {
837 if (VisitDeclaratorDecl(D))
838 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000839
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000840 if (Expr *Init = D->getInit())
841 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000842
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000843 return false;
844}
845
Douglas Gregor84b51d72010-09-01 20:16:53 +0000846bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
847 if (VisitDeclaratorDecl(D))
848 return true;
849
850 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
851 if (Expr *DefArg = D->getDefaultArgument())
852 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
853
854 return false;
855}
856
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000857bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
858 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
859 // before visiting these template parameters.
860 if (VisitTemplateParameters(D->getTemplateParameters()))
861 return true;
862
863 return VisitFunctionDecl(D->getTemplatedDecl());
864}
865
Douglas Gregor39d6f072010-08-31 19:02:00 +0000866bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
867 // FIXME: Visit the "outer" template parameter lists on the TagDecl
868 // before visiting these template parameters.
869 if (VisitTemplateParameters(D->getTemplateParameters()))
870 return true;
871
872 return VisitCXXRecordDecl(D->getTemplatedDecl());
873}
874
Douglas Gregor84b51d72010-09-01 20:16:53 +0000875bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
876 if (VisitTemplateParameters(D->getTemplateParameters()))
877 return true;
878
879 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
880 VisitTemplateArgumentLoc(D->getDefaultArgument()))
881 return true;
882
883 return false;
884}
885
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000886bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor4bc1cb62010-03-08 14:59:44 +0000887 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
888 if (Visit(TSInfo->getTypeLoc()))
889 return true;
890
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000891 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000892 PEnd = ND->param_end();
893 P != PEnd; ++P) {
894 if (Visit(MakeCXCursor(*P, TU)))
895 return true;
896 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000897
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000898 if (ND->isThisDeclarationADefinition() &&
899 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
900 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000901
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000902 return false;
903}
904
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000905namespace {
906 struct ContainerDeclsSort {
907 SourceManager &SM;
908 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
909 bool operator()(Decl *A, Decl *B) {
910 SourceLocation L_A = A->getLocStart();
911 SourceLocation L_B = B->getLocStart();
912 assert(L_A.isValid() && L_B.isValid());
913 return SM.isBeforeInTranslationUnit(L_A, L_B);
914 }
915 };
916}
917
Douglas Gregora59e3902010-01-21 23:27:09 +0000918bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000919 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
920 // an @implementation can lexically contain Decls that are not properly
921 // nested in the AST. When we identify such cases, we need to retrofit
922 // this nesting here.
923 if (!DI_current)
924 return VisitDeclContext(D);
925
926 // Scan the Decls that immediately come after the container
927 // in the current DeclContext. If any fall within the
928 // container's lexical region, stash them into a vector
929 // for later processing.
930 llvm::SmallVector<Decl *, 24> DeclsInContainer;
931 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000932 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000933 if (EndLoc.isValid()) {
934 DeclContext::decl_iterator next = *DI_current;
935 while (++next != DE_current) {
936 Decl *D_next = *next;
937 if (!D_next)
938 break;
939 SourceLocation L = D_next->getLocStart();
940 if (!L.isValid())
941 break;
942 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
943 *DI_current = next;
944 DeclsInContainer.push_back(D_next);
945 continue;
946 }
947 break;
948 }
949 }
950
951 // The common case.
952 if (DeclsInContainer.empty())
953 return VisitDeclContext(D);
954
955 // Get all the Decls in the DeclContext, and sort them with the
956 // additional ones we've collected. Then visit them.
957 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
958 I!=E; ++I) {
959 Decl *subDecl = *I;
Ted Kremenek0582c892010-11-02 23:17:51 +0000960 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
961 subDecl->getLocStart().isInvalid())
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000962 continue;
963 DeclsInContainer.push_back(subDecl);
964 }
965
966 // Now sort the Decls so that they appear in lexical order.
967 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
968 ContainerDeclsSort(SM));
969
970 // Now visit the decls.
971 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
972 E = DeclsInContainer.end(); I != E; ++I) {
973 CXCursor Cursor = MakeCXCursor(*I, TU);
974 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
975 if (!V.hasValue())
976 continue;
977 if (!V.getValue())
978 return false;
979 if (Visit(Cursor, true))
980 return true;
981 }
982 return false;
Douglas Gregora59e3902010-01-21 23:27:09 +0000983}
984
Douglas Gregorb1373d02010-01-20 20:59:29 +0000985bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000986 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
987 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000988 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000989
Douglas Gregor78db0cd2010-01-16 15:44:18 +0000990 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
991 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
992 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000993 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000994 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000995
Douglas Gregora59e3902010-01-21 23:27:09 +0000996 return VisitObjCContainerDecl(ND);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000997}
998
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000999bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1000 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1001 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1002 E = PID->protocol_end(); I != E; ++I, ++PL)
1003 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1004 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001005
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001006 return VisitObjCContainerDecl(PID);
1007}
1008
Ted Kremenek23173d72010-05-18 21:09:07 +00001009bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor83cb9422010-09-09 17:09:21 +00001010 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCallfc929202010-06-04 22:33:30 +00001011 return true;
1012
Ted Kremenek23173d72010-05-18 21:09:07 +00001013 // FIXME: This implements a workaround with @property declarations also being
1014 // installed in the DeclContext for the @interface. Eventually this code
1015 // should be removed.
1016 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1017 if (!CDecl || !CDecl->IsClassExtension())
1018 return false;
1019
1020 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1021 if (!ID)
1022 return false;
1023
1024 IdentifierInfo *PropertyId = PD->getIdentifier();
1025 ObjCPropertyDecl *prevDecl =
1026 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1027
1028 if (!prevDecl)
1029 return false;
1030
1031 // Visit synthesized methods since they will be skipped when visiting
1032 // the @interface.
1033 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001034 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001035 if (Visit(MakeCXCursor(MD, TU)))
1036 return true;
1037
1038 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001039 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001040 if (Visit(MakeCXCursor(MD, TU)))
1041 return true;
1042
1043 return false;
1044}
1045
Douglas Gregorb1373d02010-01-20 20:59:29 +00001046bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001047 // Issue callbacks for super class.
Douglas Gregorb1373d02010-01-20 20:59:29 +00001048 if (D->getSuperClass() &&
1049 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001050 D->getSuperClassLoc(),
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001051 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001052 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001053
Douglas Gregor78db0cd2010-01-16 15:44:18 +00001054 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1055 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1056 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001057 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001058 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001059
Douglas Gregora59e3902010-01-21 23:27:09 +00001060 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001061}
1062
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001063bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1064 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001065}
1066
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001067bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremenekebfa3392010-03-19 20:39:03 +00001068 // 'ID' could be null when dealing with invalid code.
1069 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1070 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1071 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001072
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001073 return VisitObjCImplDecl(D);
1074}
1075
1076bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1077#if 0
1078 // Issue callbacks for super class.
1079 // FIXME: No source location information!
1080 if (D->getSuperClass() &&
1081 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001082 D->getSuperClassLoc(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001083 TU)))
1084 return true;
1085#endif
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001086
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001087 return VisitObjCImplDecl(D);
1088}
1089
1090bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1091 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1092 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1093 E = D->protocol_end();
1094 I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001095 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001096 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001097
1098 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001099}
1100
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001101bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1102 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1103 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1104 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001105
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001106 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001107}
1108
Douglas Gregora4ffd852010-11-17 01:03:52 +00001109bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1110 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1111 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1112
1113 return false;
1114}
1115
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00001116bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1117 return VisitDeclContext(D);
1118}
1119
Douglas Gregor69319002010-08-31 23:48:11 +00001120bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001121 // Visit nested-name-specifier.
Douglas Gregor0cfaf6a2011-02-25 17:08:07 +00001122 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1123 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001124 return true;
Douglas Gregor69319002010-08-31 23:48:11 +00001125
1126 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1127 D->getTargetNameLoc(), TU));
1128}
1129
Douglas Gregor7e242562010-09-01 19:52:22 +00001130bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001131 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001132 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1133 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001134 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001135 }
Douglas Gregor7e242562010-09-01 19:52:22 +00001136
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001137 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1138 return true;
1139
Douglas Gregor7e242562010-09-01 19:52:22 +00001140 return VisitDeclarationNameInfo(D->getNameInfo());
1141}
1142
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001143bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001144 // Visit nested-name-specifier.
Douglas Gregordb992412011-02-25 16:33:46 +00001145 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1146 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001147 return true;
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001148
1149 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1150 D->getIdentLocation(), TU));
1151}
1152
Douglas Gregor7e242562010-09-01 19:52:22 +00001153bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *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;
Douglas Gregordc355712011-02-25 00:36:19 +00001158 }
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001159
Douglas Gregor7e242562010-09-01 19:52:22 +00001160 return VisitDeclarationNameInfo(D->getNameInfo());
1161}
1162
1163bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1164 UnresolvedUsingTypenameDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001165 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001168 return true;
1169
Douglas Gregor7e242562010-09-01 19:52:22 +00001170 return false;
1171}
1172
Douglas Gregor01829d32010-08-31 14:41:23 +00001173bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1174 switch (Name.getName().getNameKind()) {
1175 case clang::DeclarationName::Identifier:
1176 case clang::DeclarationName::CXXLiteralOperatorName:
1177 case clang::DeclarationName::CXXOperatorName:
1178 case clang::DeclarationName::CXXUsingDirective:
1179 return false;
1180
1181 case clang::DeclarationName::CXXConstructorName:
1182 case clang::DeclarationName::CXXDestructorName:
1183 case clang::DeclarationName::CXXConversionFunctionName:
1184 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1185 return Visit(TSInfo->getTypeLoc());
1186 return false;
1187
1188 case clang::DeclarationName::ObjCZeroArgSelector:
1189 case clang::DeclarationName::ObjCOneArgSelector:
1190 case clang::DeclarationName::ObjCMultiArgSelector:
1191 // FIXME: Per-identifier location info?
1192 return false;
1193 }
1194
1195 return false;
1196}
1197
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001198bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1199 SourceRange Range) {
1200 // FIXME: This whole routine is a hack to work around the lack of proper
1201 // source information in nested-name-specifiers (PR5791). Since we do have
1202 // a beginning source location, we can visit the first component of the
1203 // nested-name-specifier, if it's a single-token component.
1204 if (!NNS)
1205 return false;
1206
1207 // Get the first component in the nested-name-specifier.
1208 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1209 NNS = Prefix;
1210
1211 switch (NNS->getKind()) {
1212 case NestedNameSpecifier::Namespace:
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001213 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1214 TU));
1215
Douglas Gregor14aba762011-02-24 02:36:08 +00001216 case NestedNameSpecifier::NamespaceAlias:
1217 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1218 Range.getBegin(), TU));
1219
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001220 case NestedNameSpecifier::TypeSpec: {
1221 // If the type has a form where we know that the beginning of the source
1222 // range matches up with a reference cursor. Visit the appropriate reference
1223 // cursor.
John McCallf4c73712011-01-19 06:33:43 +00001224 const Type *T = NNS->getAsType();
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001225 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1226 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1227 if (const TagType *Tag = dyn_cast<TagType>(T))
1228 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1229 if (const TemplateSpecializationType *TST
1230 = dyn_cast<TemplateSpecializationType>(T))
1231 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1232 break;
1233 }
1234
1235 case NestedNameSpecifier::TypeSpecWithTemplate:
1236 case NestedNameSpecifier::Global:
1237 case NestedNameSpecifier::Identifier:
1238 break;
1239 }
1240
1241 return false;
1242}
1243
Douglas Gregordc355712011-02-25 00:36:19 +00001244bool
1245CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1246 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1247 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1248 Qualifiers.push_back(Qualifier);
1249
1250 while (!Qualifiers.empty()) {
1251 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1252 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1253 switch (NNS->getKind()) {
1254 case NestedNameSpecifier::Namespace:
1255 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001256 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001257 TU)))
1258 return true;
1259
1260 break;
1261
1262 case NestedNameSpecifier::NamespaceAlias:
1263 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001264 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001265 TU)))
1266 return true;
1267
1268 break;
1269
1270 case NestedNameSpecifier::TypeSpec:
1271 case NestedNameSpecifier::TypeSpecWithTemplate:
1272 if (Visit(Q.getTypeLoc()))
1273 return true;
1274
1275 break;
1276
1277 case NestedNameSpecifier::Global:
1278 case NestedNameSpecifier::Identifier:
1279 break;
1280 }
1281 }
1282
1283 return false;
1284}
1285
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001286bool CursorVisitor::VisitTemplateParameters(
1287 const TemplateParameterList *Params) {
1288 if (!Params)
1289 return false;
1290
1291 for (TemplateParameterList::const_iterator P = Params->begin(),
1292 PEnd = Params->end();
1293 P != PEnd; ++P) {
1294 if (Visit(MakeCXCursor(*P, TU)))
1295 return true;
1296 }
1297
1298 return false;
1299}
1300
Douglas Gregor0b36e612010-08-31 20:37:03 +00001301bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1302 switch (Name.getKind()) {
1303 case TemplateName::Template:
1304 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1305
1306 case TemplateName::OverloadedTemplate:
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001307 // Visit the overloaded template set.
1308 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1309 return true;
1310
Douglas Gregor0b36e612010-08-31 20:37:03 +00001311 return false;
1312
1313 case TemplateName::DependentTemplate:
1314 // FIXME: Visit nested-name-specifier.
1315 return false;
1316
1317 case TemplateName::QualifiedTemplate:
1318 // FIXME: Visit nested-name-specifier.
1319 return Visit(MakeCursorTemplateRef(
1320 Name.getAsQualifiedTemplateName()->getDecl(),
1321 Loc, TU));
Douglas Gregor1aee05d2011-01-15 06:45:20 +00001322
1323 case TemplateName::SubstTemplateTemplateParmPack:
1324 return Visit(MakeCursorTemplateRef(
1325 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1326 Loc, TU));
Douglas Gregor0b36e612010-08-31 20:37:03 +00001327 }
1328
1329 return false;
1330}
1331
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001332bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1333 switch (TAL.getArgument().getKind()) {
1334 case TemplateArgument::Null:
1335 case TemplateArgument::Integral:
Douglas Gregor87dd6972010-12-20 16:52:59 +00001336 case TemplateArgument::Pack:
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001337 return false;
1338
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001339 case TemplateArgument::Type:
1340 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1341 return Visit(TSInfo->getTypeLoc());
1342 return false;
1343
1344 case TemplateArgument::Declaration:
1345 if (Expr *E = TAL.getSourceDeclExpression())
1346 return Visit(MakeCXCursor(E, StmtParent, TU));
1347 return false;
1348
1349 case TemplateArgument::Expression:
1350 if (Expr *E = TAL.getSourceExpression())
1351 return Visit(MakeCXCursor(E, StmtParent, TU));
1352 return false;
1353
1354 case TemplateArgument::Template:
Douglas Gregora7fc9012011-01-05 18:58:31 +00001355 case TemplateArgument::TemplateExpansion:
Douglas Gregorb6744ef2011-03-02 17:09:35 +00001356 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1357 return true;
1358
Douglas Gregora7fc9012011-01-05 18:58:31 +00001359 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregor0b36e612010-08-31 20:37:03 +00001360 TAL.getTemplateNameLoc());
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001361 }
1362
1363 return false;
1364}
1365
Ted Kremeneka0536d82010-05-07 01:04:29 +00001366bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1367 return VisitDeclContext(D);
1368}
1369
Douglas Gregor01829d32010-08-31 14:41:23 +00001370bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1371 return Visit(TL.getUnqualifiedLoc());
1372}
1373
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001374bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00001375 ASTContext &Context = AU->getASTContext();
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001376
1377 // Some builtin types (such as Objective-C's "id", "sel", and
1378 // "Class") have associated declarations. Create cursors for those.
1379 QualType VisitType;
1380 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001381 case BuiltinType::Void:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001382 case BuiltinType::Bool:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001383 case BuiltinType::Char_U:
1384 case BuiltinType::UChar:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001385 case BuiltinType::Char16:
1386 case BuiltinType::Char32:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001387 case BuiltinType::UShort:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001388 case BuiltinType::UInt:
1389 case BuiltinType::ULong:
1390 case BuiltinType::ULongLong:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001391 case BuiltinType::UInt128:
1392 case BuiltinType::Char_S:
1393 case BuiltinType::SChar:
Chris Lattner3f59c972010-12-25 23:25:43 +00001394 case BuiltinType::WChar_U:
1395 case BuiltinType::WChar_S:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001396 case BuiltinType::Short:
1397 case BuiltinType::Int:
1398 case BuiltinType::Long:
1399 case BuiltinType::LongLong:
1400 case BuiltinType::Int128:
1401 case BuiltinType::Float:
1402 case BuiltinType::Double:
1403 case BuiltinType::LongDouble:
1404 case BuiltinType::NullPtr:
1405 case BuiltinType::Overload:
1406 case BuiltinType::Dependent:
John McCall1de4d4e2011-04-07 08:22:57 +00001407 case BuiltinType::UnknownAny:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001408 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001409
Ted Kremenekc4174cc2010-02-18 18:52:18 +00001410 case BuiltinType::ObjCId:
1411 VisitType = Context.getObjCIdType();
1412 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001413
1414 case BuiltinType::ObjCClass:
1415 VisitType = Context.getObjCClassType();
1416 break;
1417
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001418 case BuiltinType::ObjCSel:
1419 VisitType = Context.getObjCSelType();
1420 break;
1421 }
1422
1423 if (!VisitType.isNull()) {
1424 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001425 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001426 TU));
1427 }
1428
1429 return false;
1430}
1431
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001432bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1433 return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
1434}
1435
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001436bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1437 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1438}
1439
1440bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1441 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1442}
1443
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001444bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001445 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001446 // no context information with which we can match up the depth/index in the
1447 // type to the appropriate
1448 return false;
1449}
1450
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001451bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1452 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1453 return true;
1454
John McCallc12c5bb2010-05-15 11:32:37 +00001455 return false;
1456}
1457
1458bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1459 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1460 return true;
1461
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001462 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1463 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1464 TU)))
1465 return true;
1466 }
1467
1468 return false;
1469}
1470
1471bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCallc12c5bb2010-05-15 11:32:37 +00001472 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001473}
1474
Abramo Bagnara075f8f12010-12-10 16:29:40 +00001475bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1476 return Visit(TL.getInnerLoc());
1477}
1478
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001479bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1480 return Visit(TL.getPointeeLoc());
1481}
1482
1483bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1484 return Visit(TL.getPointeeLoc());
1485}
1486
1487bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1488 return Visit(TL.getPointeeLoc());
1489}
1490
1491bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001492 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001493}
1494
1495bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001496 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001497}
1498
Douglas Gregor01829d32010-08-31 14:41:23 +00001499bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1500 bool SkipResultType) {
1501 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001502 return true;
1503
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001504 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek5dbacb42010-04-07 00:27:13 +00001505 if (Decl *D = TL.getArg(I))
1506 if (Visit(MakeCXCursor(D, TU)))
1507 return true;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001508
1509 return false;
1510}
1511
1512bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1513 if (Visit(TL.getElementLoc()))
1514 return true;
1515
1516 if (Expr *Size = TL.getSizeExpr())
1517 return Visit(MakeCXCursor(Size, StmtParent, TU));
1518
1519 return false;
1520}
1521
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001522bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1523 TemplateSpecializationTypeLoc TL) {
Douglas Gregor0b36e612010-08-31 20:37:03 +00001524 // Visit the template name.
1525 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1526 TL.getTemplateNameLoc()))
1527 return true;
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001528
1529 // Visit the template arguments.
1530 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1531 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1532 return true;
1533
1534 return false;
1535}
1536
Douglas Gregor2332c112010-01-21 20:48:56 +00001537bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1538 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1539}
1540
1541bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1542 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1543 return Visit(TSInfo->getTypeLoc());
1544
1545 return false;
1546}
1547
Douglas Gregor2494dd02011-03-01 01:34:45 +00001548bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1549 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1550 return true;
1551
1552 return false;
1553}
1554
Douglas Gregor94fdffa2011-03-01 20:11:18 +00001555bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1556 DependentTemplateSpecializationTypeLoc TL) {
1557 // Visit the nested-name-specifier, if there is one.
1558 if (TL.getQualifierLoc() &&
1559 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1560 return true;
1561
1562 // Visit the template arguments.
1563 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1564 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1565 return true;
1566
1567 return false;
1568}
1569
Douglas Gregor9e876872011-03-01 18:12:44 +00001570bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1571 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1572 return true;
1573
1574 return Visit(TL.getNamedTypeLoc());
1575}
1576
Douglas Gregor7536dd52010-12-20 02:24:11 +00001577bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1578 return Visit(TL.getPatternLoc());
1579}
1580
Ted Kremenek3064ef92010-08-27 21:34:58 +00001581bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001582 // Visit the nested-name-specifier, if present.
1583 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1584 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1585 return true;
1586
Ted Kremenek3064ef92010-08-27 21:34:58 +00001587 if (D->isDefinition()) {
1588 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1589 E = D->bases_end(); I != E; ++I) {
1590 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1591 return true;
1592 }
1593 }
1594
1595 return VisitTagDecl(D);
1596}
1597
Ted Kremenek09dfa372010-02-18 05:46:33 +00001598bool CursorVisitor::VisitAttributes(Decl *D) {
Sean Huntcf807c42010-08-18 23:23:40 +00001599 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1600 i != e; ++i)
1601 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek09dfa372010-02-18 05:46:33 +00001602 return true;
1603
1604 return false;
1605}
1606
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001607//===----------------------------------------------------------------------===//
1608// Data-recursive visitor methods.
1609//===----------------------------------------------------------------------===//
1610
Ted Kremenek28a71942010-11-13 00:36:47 +00001611namespace {
Ted Kremenek035dc412010-11-13 00:36:50 +00001612#define DEF_JOB(NAME, DATA, KIND)\
1613class NAME : public VisitorJob {\
1614public:\
1615 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1616 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenekf64d8032010-11-18 00:02:32 +00001617 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek035dc412010-11-13 00:36:50 +00001618};
1619
1620DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1621DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001622DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001623DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek60608ec2010-11-17 00:50:47 +00001624DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1625 ExplicitTemplateArgsVisitKind)
Douglas Gregor94d96292011-01-19 20:34:17 +00001626DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001627#undef DEF_JOB
1628
1629class DeclVisit : public VisitorJob {
1630public:
1631 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1632 VisitorJob(parent, VisitorJob::DeclVisitKind,
1633 d, isFirst ? (void*) 1 : (void*) 0) {}
1634 static bool classof(const VisitorJob *VJ) {
Ted Kremenek82f3c502010-11-15 22:23:26 +00001635 return VJ->getKind() == DeclVisitKind;
Ted Kremenek035dc412010-11-13 00:36:50 +00001636 }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001637 Decl *get() const { return static_cast<Decl*>(data[0]); }
1638 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek035dc412010-11-13 00:36:50 +00001639};
Ted Kremenek035dc412010-11-13 00:36:50 +00001640class TypeLocVisit : public VisitorJob {
1641public:
1642 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1643 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1644 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1645
1646 static bool classof(const VisitorJob *VJ) {
1647 return VJ->getKind() == TypeLocVisitKind;
1648 }
1649
Ted Kremenek82f3c502010-11-15 22:23:26 +00001650 TypeLoc get() const {
Ted Kremenekf64d8032010-11-18 00:02:32 +00001651 QualType T = QualType::getFromOpaquePtr(data[0]);
1652 return TypeLoc(T, data[1]);
Ted Kremenek035dc412010-11-13 00:36:50 +00001653 }
1654};
1655
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001656class LabelRefVisit : public VisitorJob {
1657public:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001658 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1659 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001660 labelLoc.getPtrEncoding()) {}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001661
1662 static bool classof(const VisitorJob *VJ) {
1663 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1664 }
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001665 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001666 SourceLocation getLoc() const {
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001667 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001668};
1669class NestedNameSpecifierVisit : public VisitorJob {
1670public:
1671 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1672 CXCursor parent)
1673 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001674 NS, R.getBegin().getPtrEncoding(),
1675 R.getEnd().getPtrEncoding()) {}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001676 static bool classof(const VisitorJob *VJ) {
1677 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1678 }
1679 NestedNameSpecifier *get() const {
1680 return static_cast<NestedNameSpecifier*>(data[0]);
1681 }
1682 SourceRange getSourceRange() const {
1683 SourceLocation A =
1684 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1685 SourceLocation B =
1686 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1687 return SourceRange(A, B);
1688 }
1689};
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001690
1691class NestedNameSpecifierLocVisit : public VisitorJob {
1692public:
1693 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1694 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1695 Qualifier.getNestedNameSpecifier(),
1696 Qualifier.getOpaqueData()) { }
1697
1698 static bool classof(const VisitorJob *VJ) {
1699 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1700 }
1701
1702 NestedNameSpecifierLoc get() const {
1703 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1704 data[1]);
1705 }
1706};
1707
Ted Kremenekf64d8032010-11-18 00:02:32 +00001708class DeclarationNameInfoVisit : public VisitorJob {
1709public:
1710 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1711 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1714 }
1715 DeclarationNameInfo get() const {
1716 Stmt *S = static_cast<Stmt*>(data[0]);
1717 switch (S->getStmtClass()) {
1718 default:
1719 llvm_unreachable("Unhandled Stmt");
1720 case Stmt::CXXDependentScopeMemberExprClass:
1721 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1722 case Stmt::DependentScopeDeclRefExprClass:
1723 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1724 }
1725 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001726};
Ted Kremenekcdba6592010-11-18 00:42:18 +00001727class MemberRefVisit : public VisitorJob {
1728public:
1729 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1730 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001731 L.getPtrEncoding()) {}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001732 static bool classof(const VisitorJob *VJ) {
1733 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1734 }
1735 FieldDecl *get() const {
1736 return static_cast<FieldDecl*>(data[0]);
1737 }
1738 SourceLocation getLoc() const {
1739 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1740 }
1741};
Ted Kremenek28a71942010-11-13 00:36:47 +00001742class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1743 VisitorWorkList &WL;
1744 CXCursor Parent;
1745public:
1746 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1747 : WL(wl), Parent(parent) {}
1748
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001749 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001750 void VisitBlockExpr(BlockExpr *B);
Ted Kremenek28a71942010-11-13 00:36:47 +00001751 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenek083c7e22010-11-13 05:38:03 +00001752 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001753 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001754 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001755 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001756 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001757 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001758 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001759 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001760 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek55b933a2010-11-17 00:50:36 +00001761 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001762 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001763 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek035dc412010-11-13 00:36:50 +00001764 void VisitDeclStmt(DeclStmt *S);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001765 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001766 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001767 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1768 void VisitForStmt(ForStmt *FS);
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001769 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenek28a71942010-11-13 00:36:47 +00001770 void VisitIfStmt(IfStmt *If);
1771 void VisitInitListExpr(InitListExpr *IE);
1772 void VisitMemberExpr(MemberExpr *M);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001773 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001774 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001775 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1776 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00001777 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001778 void VisitStmt(Stmt *S);
1779 void VisitSwitchStmt(SwitchStmt *S);
1780 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek2939b6f2010-11-17 00:50:50 +00001781 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet6ad6f282010-12-07 00:08:36 +00001782 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001783 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenek9d3bf792010-11-17 00:50:43 +00001784 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor94d96292011-01-19 20:34:17 +00001785 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregoree8aff02011-01-04 17:33:58 +00001786
Ted Kremenek28a71942010-11-13 00:36:47 +00001787private:
Ted Kremenekf64d8032010-11-18 00:02:32 +00001788 void AddDeclarationNameInfo(Stmt *S);
1789 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001790 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek60608ec2010-11-17 00:50:47 +00001791 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001792 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenek28a71942010-11-13 00:36:47 +00001793 void AddStmt(Stmt *S);
Ted Kremenek035dc412010-11-13 00:36:50 +00001794 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenek28a71942010-11-13 00:36:47 +00001795 void AddTypeLoc(TypeSourceInfo *TI);
1796 void EnqueueChildren(Stmt *S);
1797};
1798} // end anonyous namespace
1799
Ted Kremenekf64d8032010-11-18 00:02:32 +00001800void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1801 // 'S' should always be non-null, since it comes from the
1802 // statement we are visiting.
1803 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1804}
1805void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1806 SourceRange R) {
1807 if (N)
1808 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1809}
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001810
1811void
1812EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1813 if (Qualifier)
1814 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1815}
1816
Ted Kremenek28a71942010-11-13 00:36:47 +00001817void EnqueueVisitor::AddStmt(Stmt *S) {
1818 if (S)
1819 WL.push_back(StmtVisit(S, Parent));
1820}
Ted Kremenek035dc412010-11-13 00:36:50 +00001821void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001822 if (D)
Ted Kremenek035dc412010-11-13 00:36:50 +00001823 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenek28a71942010-11-13 00:36:47 +00001824}
Ted Kremenek60608ec2010-11-17 00:50:47 +00001825void EnqueueVisitor::
1826 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1827 if (A)
1828 WL.push_back(ExplicitTemplateArgsVisit(
1829 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1830}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001831void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1832 if (D)
1833 WL.push_back(MemberRefVisit(D, L, Parent));
1834}
Ted Kremenek28a71942010-11-13 00:36:47 +00001835void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1836 if (TI)
1837 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1838 }
1839void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremeneka6b70432010-11-12 21:34:09 +00001840 unsigned size = WL.size();
John McCall7502c1d2011-02-13 04:07:26 +00001841 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001842 AddStmt(*Child);
Ted Kremeneka6b70432010-11-12 21:34:09 +00001843 }
1844 if (size == WL.size())
1845 return;
1846 // Now reverse the entries we just added. This will match the DFS
1847 // ordering performed by the worklist.
1848 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1849 std::reverse(I, E);
1850}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001851void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1852 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1853}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001854void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1855 AddDecl(B->getBlockDecl());
1856}
Ted Kremenek28a71942010-11-13 00:36:47 +00001857void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1858 EnqueueChildren(E);
1859 AddTypeLoc(E->getTypeSourceInfo());
1860}
Ted Kremenek083c7e22010-11-13 05:38:03 +00001861void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1862 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1863 E = S->body_rend(); I != E; ++I) {
1864 AddStmt(*I);
1865 }
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001866}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001867void EnqueueVisitor::
1868VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1869 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1870 AddDeclarationNameInfo(E);
Douglas Gregor7c3179c2011-02-28 18:50:33 +00001871 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1872 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001873 if (!E->isImplicitAccess())
1874 AddStmt(E->getBase());
1875}
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001876void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1877 // Enqueue the initializer or constructor arguments.
1878 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1879 AddStmt(E->getConstructorArg(I-1));
1880 // Enqueue the array size, if any.
1881 AddStmt(E->getArraySize());
1882 // Enqueue the allocated type.
1883 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1884 // Enqueue the placement arguments.
1885 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1886 AddStmt(E->getPlacementArg(I-1));
1887}
Ted Kremenek28a71942010-11-13 00:36:47 +00001888void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenek8b8d8c92010-11-13 05:55:56 +00001889 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1890 AddStmt(CE->getArg(I-1));
Ted Kremenek28a71942010-11-13 00:36:47 +00001891 AddStmt(CE->getCallee());
1892 AddStmt(CE->getArg(0));
1893}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001894void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1895 // Visit the name of the type being destroyed.
1896 AddTypeLoc(E->getDestroyedTypeInfo());
1897 // Visit the scope type that looks disturbingly like the nested-name-specifier
1898 // but isn't.
1899 AddTypeLoc(E->getScopeTypeInfo());
1900 // Visit the nested-name-specifier.
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001901 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1902 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001903 // Visit base expression.
1904 AddStmt(E->getBase());
1905}
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001906void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1907 AddTypeLoc(E->getTypeSourceInfo());
1908}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001909void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1910 EnqueueChildren(E);
1911 AddTypeLoc(E->getTypeSourceInfo());
1912}
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001913void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1914 EnqueueChildren(E);
1915 if (E->isTypeOperand())
1916 AddTypeLoc(E->getTypeOperandSourceInfo());
1917}
Ted Kremenek55b933a2010-11-17 00:50:36 +00001918
1919void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1920 *E) {
1921 EnqueueChildren(E);
1922 AddTypeLoc(E->getTypeSourceInfo());
1923}
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001924void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1925 EnqueueChildren(E);
1926 if (E->isTypeOperand())
1927 AddTypeLoc(E->getTypeOperandSourceInfo());
1928}
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001929void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00001930 if (DR->hasExplicitTemplateArgs()) {
1931 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1932 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001933 WL.push_back(DeclRefExprParts(DR, Parent));
1934}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001935void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1936 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1937 AddDeclarationNameInfo(E);
Douglas Gregor00cf3cc2011-02-25 20:49:16 +00001938 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenekf64d8032010-11-18 00:02:32 +00001939}
Ted Kremenek035dc412010-11-13 00:36:50 +00001940void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1941 unsigned size = WL.size();
1942 bool isFirst = true;
1943 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1944 D != DEnd; ++D) {
1945 AddDecl(*D, isFirst);
1946 isFirst = false;
1947 }
1948 if (size == WL.size())
1949 return;
1950 // Now reverse the entries we just added. This will match the DFS
1951 // ordering performed by the worklist.
1952 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1953 std::reverse(I, E);
1954}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001955void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1956 AddStmt(E->getInit());
1957 typedef DesignatedInitExpr::Designator Designator;
1958 for (DesignatedInitExpr::reverse_designators_iterator
1959 D = E->designators_rbegin(), DEnd = E->designators_rend();
1960 D != DEnd; ++D) {
1961 if (D->isFieldDesignator()) {
1962 if (FieldDecl *Field = D->getField())
1963 AddMemberRef(Field, D->getFieldLoc());
1964 continue;
1965 }
1966 if (D->isArrayDesignator()) {
1967 AddStmt(E->getArrayIndex(*D));
1968 continue;
1969 }
1970 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1971 AddStmt(E->getArrayRangeEnd(*D));
1972 AddStmt(E->getArrayRangeStart(*D));
1973 }
1974}
Ted Kremenek28a71942010-11-13 00:36:47 +00001975void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1976 EnqueueChildren(E);
1977 AddTypeLoc(E->getTypeInfoAsWritten());
1978}
1979void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1980 AddStmt(FS->getBody());
1981 AddStmt(FS->getInc());
1982 AddStmt(FS->getCond());
1983 AddDecl(FS->getConditionVariable());
1984 AddStmt(FS->getInit());
1985}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001986void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1987 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1988}
Ted Kremenek28a71942010-11-13 00:36:47 +00001989void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
1990 AddStmt(If->getElse());
1991 AddStmt(If->getThen());
1992 AddStmt(If->getCond());
1993 AddDecl(If->getConditionVariable());
1994}
1995void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
1996 // We care about the syntactic form of the initializer list, only.
1997 if (InitListExpr *Syntactic = IE->getSyntacticForm())
1998 IE = Syntactic;
1999 EnqueueChildren(IE);
2000}
2001void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor89629a72010-11-17 17:15:08 +00002002 WL.push_back(MemberExprParts(M, Parent));
2003
2004 // If the base of the member access expression is an implicit 'this', don't
2005 // visit it.
2006 // FIXME: If we ever want to show these implicit accesses, this will be
2007 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor75e85042011-03-02 21:06:53 +00002008 if (!M->isImplicitAccess())
2009 AddStmt(M->getBase());
Ted Kremenek28a71942010-11-13 00:36:47 +00002010}
Ted Kremenek73d15c42010-11-13 01:09:29 +00002011void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2012 AddTypeLoc(E->getEncodedTypeSourceInfo());
2013}
Ted Kremenek28a71942010-11-13 00:36:47 +00002014void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2015 EnqueueChildren(M);
2016 AddTypeLoc(M->getClassReceiverTypeInfo());
2017}
Ted Kremenekcdba6592010-11-18 00:42:18 +00002018void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2019 // Visit the components of the offsetof expression.
2020 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2021 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2022 const OffsetOfNode &Node = E->getComponent(I-1);
2023 switch (Node.getKind()) {
2024 case OffsetOfNode::Array:
2025 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2026 break;
2027 case OffsetOfNode::Field:
Abramo Bagnara06dec892011-03-12 09:45:03 +00002028 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenekcdba6592010-11-18 00:42:18 +00002029 break;
2030 case OffsetOfNode::Identifier:
2031 case OffsetOfNode::Base:
2032 continue;
2033 }
2034 }
2035 // Visit the type into which we're computing the offset.
2036 AddTypeLoc(E->getTypeSourceInfo());
2037}
Ted Kremenek28a71942010-11-13 00:36:47 +00002038void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00002039 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenek60458782010-11-12 21:34:16 +00002040 WL.push_back(OverloadExprParts(E, Parent));
2041}
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00002042void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2043 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00002044 EnqueueChildren(E);
2045 if (E->isArgumentType())
2046 AddTypeLoc(E->getArgumentTypeInfo());
2047}
Ted Kremenek28a71942010-11-13 00:36:47 +00002048void EnqueueVisitor::VisitStmt(Stmt *S) {
2049 EnqueueChildren(S);
2050}
2051void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2052 AddStmt(S->getBody());
2053 AddStmt(S->getCond());
2054 AddDecl(S->getConditionVariable());
2055}
Ted Kremenekfafa75a2010-11-17 00:50:39 +00002056
Ted Kremenek28a71942010-11-13 00:36:47 +00002057void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2058 AddStmt(W->getBody());
2059 AddStmt(W->getCond());
2060 AddDecl(W->getConditionVariable());
2061}
Ted Kremenek2939b6f2010-11-17 00:50:50 +00002062void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2063 AddTypeLoc(E->getQueriedTypeSourceInfo());
2064}
Francois Pichet6ad6f282010-12-07 00:08:36 +00002065
2066void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet6ad6f282010-12-07 00:08:36 +00002067 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichet0a03a3f2010-12-08 09:11:05 +00002068 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet6ad6f282010-12-07 00:08:36 +00002069}
2070
Ted Kremenek28a71942010-11-13 00:36:47 +00002071void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2072 VisitOverloadExpr(U);
2073 if (!U->isImplicitAccess())
2074 AddStmt(U->getBase());
2075}
Ted Kremenek9d3bf792010-11-17 00:50:43 +00002076void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2077 AddStmt(E->getSubExpr());
2078 AddTypeLoc(E->getWrittenTypeInfo());
2079}
Douglas Gregor94d96292011-01-19 20:34:17 +00002080void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2081 WL.push_back(SizeOfPackExprParts(E, Parent));
2082}
Ted Kremenek60458782010-11-12 21:34:16 +00002083
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002084void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenek28a71942010-11-13 00:36:47 +00002085 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002086}
2087
2088bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2089 if (RegionOfInterest.isValid()) {
2090 SourceRange Range = getRawCursorExtent(C);
2091 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2092 return false;
2093 }
2094 return true;
2095}
2096
2097bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2098 while (!WL.empty()) {
2099 // Dequeue the worklist item.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002100 VisitorJob LI = WL.back();
2101 WL.pop_back();
2102
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002103 // Set the Parent field, then back to its old value once we're done.
2104 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2105
2106 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00002107 case VisitorJob::DeclVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002108 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenekf1107452010-11-12 18:26:56 +00002109 if (!D)
2110 continue;
2111
2112 // For now, perform default visitation for Decls.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002113 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenekf1107452010-11-12 18:26:56 +00002114 return true;
2115
2116 continue;
2117 }
Ted Kremenek60608ec2010-11-17 00:50:47 +00002118 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2119 const ExplicitTemplateArgumentList *ArgList =
2120 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2121 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2122 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2123 Arg != ArgEnd; ++Arg) {
2124 if (VisitTemplateArgumentLoc(*Arg))
2125 return true;
2126 }
2127 continue;
2128 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002129 case VisitorJob::TypeLocVisitKind: {
2130 // Perform default visitation for TypeLocs.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002131 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002132 return true;
2133 continue;
2134 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002135 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002136 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremeneke7455012011-02-23 04:54:51 +00002137 if (LabelStmt *stmt = LS->getStmt()) {
2138 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2139 TU))) {
2140 return true;
2141 }
2142 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002143 continue;
2144 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002145
Ted Kremenekf64d8032010-11-18 00:02:32 +00002146 case VisitorJob::NestedNameSpecifierVisitKind: {
2147 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2148 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2149 return true;
2150 continue;
2151 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002152
2153 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2154 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2155 if (VisitNestedNameSpecifierLoc(V->get()))
2156 return true;
2157 continue;
2158 }
2159
Ted Kremenekf64d8032010-11-18 00:02:32 +00002160 case VisitorJob::DeclarationNameInfoVisitKind: {
2161 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2162 ->get()))
2163 return true;
2164 continue;
2165 }
Ted Kremenekcdba6592010-11-18 00:42:18 +00002166 case VisitorJob::MemberRefVisitKind: {
2167 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2168 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2169 return true;
2170 continue;
2171 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002172 case VisitorJob::StmtVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002173 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002174 if (!S)
2175 continue;
2176
Ted Kremenekf1107452010-11-12 18:26:56 +00002177 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002178 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenekcdba6592010-11-18 00:42:18 +00002179 if (!IsInRegionOfInterest(Cursor))
2180 continue;
2181 switch (Visitor(Cursor, Parent, ClientData)) {
2182 case CXChildVisit_Break: return true;
2183 case CXChildVisit_Continue: break;
2184 case CXChildVisit_Recurse:
2185 EnqueueWorkList(WL, S);
Ted Kremenek82f3c502010-11-15 22:23:26 +00002186 break;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002187 }
Ted Kremenek82f3c502010-11-15 22:23:26 +00002188 continue;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002189 }
2190 case VisitorJob::MemberExprPartsKind: {
2191 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002192 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002193
2194 // Visit the nested-name-specifier
Douglas Gregor40d96a62011-02-28 21:54:11 +00002195 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2196 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002197 return true;
2198
2199 // Visit the declaration name.
2200 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2201 return true;
2202
2203 // Visit the explicitly-specified template arguments, if any.
2204 if (M->hasExplicitTemplateArgs()) {
2205 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2206 *ArgEnd = Arg + M->getNumTemplateArgs();
2207 Arg != ArgEnd; ++Arg) {
2208 if (VisitTemplateArgumentLoc(*Arg))
2209 return true;
2210 }
2211 }
2212 continue;
2213 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002214 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002215 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002216 // Visit nested-name-specifier, if present.
Douglas Gregor40d96a62011-02-28 21:54:11 +00002217 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2218 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002219 return true;
2220 // Visit declaration name.
2221 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2222 return true;
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002223 continue;
2224 }
Ted Kremenek60458782010-11-12 21:34:16 +00002225 case VisitorJob::OverloadExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002226 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenek60458782010-11-12 21:34:16 +00002227 // Visit the nested-name-specifier.
Douglas Gregor4c9be892011-02-28 20:01:57 +00002228 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2229 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek60458782010-11-12 21:34:16 +00002230 return true;
2231 // Visit the declaration name.
2232 if (VisitDeclarationNameInfo(O->getNameInfo()))
2233 return true;
2234 // Visit the overloaded declaration reference.
2235 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2236 return true;
Ted Kremenek60458782010-11-12 21:34:16 +00002237 continue;
2238 }
Douglas Gregor94d96292011-01-19 20:34:17 +00002239 case VisitorJob::SizeOfPackExprPartsKind: {
2240 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2241 NamedDecl *Pack = E->getPack();
2242 if (isa<TemplateTypeParmDecl>(Pack)) {
2243 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2244 E->getPackLoc(), TU)))
2245 return true;
2246
2247 continue;
2248 }
2249
2250 if (isa<TemplateTemplateParmDecl>(Pack)) {
2251 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2252 E->getPackLoc(), TU)))
2253 return true;
2254
2255 continue;
2256 }
2257
2258 // Non-type template parameter packs and function parameter packs are
2259 // treated like DeclRefExpr cursors.
2260 continue;
2261 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002262 }
2263 }
2264 return false;
2265}
2266
Ted Kremenekcdba6592010-11-18 00:42:18 +00002267bool CursorVisitor::Visit(Stmt *S) {
Ted Kremenekd1ded662010-11-15 23:31:32 +00002268 VisitorWorkList *WL = 0;
2269 if (!WorkListFreeList.empty()) {
2270 WL = WorkListFreeList.back();
2271 WL->clear();
2272 WorkListFreeList.pop_back();
2273 }
2274 else {
2275 WL = new VisitorWorkList();
2276 WorkListCache.push_back(WL);
2277 }
2278 EnqueueWorkList(*WL, S);
2279 bool result = RunVisitorWorkList(*WL);
2280 WorkListFreeList.push_back(WL);
2281 return result;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002282}
2283
2284//===----------------------------------------------------------------------===//
2285// Misc. API hooks.
2286//===----------------------------------------------------------------------===//
2287
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002288static llvm::sys::Mutex EnableMultithreadingMutex;
2289static bool EnabledMultithreading;
2290
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002291extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002292CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2293 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002294 // Disable pretty stack trace functionality, which will otherwise be a very
2295 // poor citizen of the world and set up all sorts of signal handlers.
2296 llvm::DisablePrettyStackTrace = true;
2297
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002298 // We use crash recovery to make some of our APIs more reliable, implicitly
2299 // enable it.
2300 llvm::CrashRecoveryContext::Enable();
2301
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002302 // Enable support for multithreading in LLVM.
2303 {
2304 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2305 if (!EnabledMultithreading) {
2306 llvm::llvm_start_multithreaded();
2307 EnabledMultithreading = true;
2308 }
2309 }
2310
Douglas Gregora030b7c2010-01-22 20:35:53 +00002311 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002312 if (excludeDeclarationsFromPCH)
2313 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002314 if (displayDiagnostics)
2315 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002316 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002317}
2318
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002319void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002320 if (CIdx)
2321 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002322}
2323
Ted Kremenekd2427dd2011-03-18 23:05:39 +00002324void clang_toggleCrashRecovery(unsigned isEnabled) {
2325 if (isEnabled)
2326 llvm::CrashRecoveryContext::Enable();
2327 else
2328 llvm::CrashRecoveryContext::Disable();
2329}
2330
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002331CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002332 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002333 if (!CIdx)
2334 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002335
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002336 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002337 FileSystemOptions FileSystemOpts;
2338 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002339
Douglas Gregor28019772010-04-05 23:52:57 +00002340 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremeneka60ed472010-11-16 08:15:36 +00002341 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002342 CXXIdx->getOnlyLocalDecls(),
2343 0, 0, true);
Ted Kremeneka60ed472010-11-16 08:15:36 +00002344 return MakeCXTranslationUnit(TU);
Steve Naroff600866c2009-08-27 19:51:58 +00002345}
2346
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002347unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002348 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002349 CXTranslationUnit_CacheCompletionResults |
2350 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002351}
2352
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002353CXTranslationUnit
2354clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2355 const char *source_filename,
2356 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002357 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002358 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002359 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor5a430212010-07-21 18:52:53 +00002360 return clang_parseTranslationUnit(CIdx, source_filename,
2361 command_line_args, num_command_line_args,
2362 unsaved_files, num_unsaved_files,
2363 CXTranslationUnit_DetailedPreprocessingRecord);
2364}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002365
2366struct ParseTranslationUnitInfo {
2367 CXIndex CIdx;
2368 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002369 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002370 int num_command_line_args;
2371 struct CXUnsavedFile *unsaved_files;
2372 unsigned num_unsaved_files;
2373 unsigned options;
2374 CXTranslationUnit result;
2375};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002376static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002377 ParseTranslationUnitInfo *PTUI =
2378 static_cast<ParseTranslationUnitInfo*>(UserData);
2379 CXIndex CIdx = PTUI->CIdx;
2380 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002381 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002382 int num_command_line_args = PTUI->num_command_line_args;
2383 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2384 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2385 unsigned options = PTUI->options;
2386 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002387
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002388 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002389 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002390
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002391 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2392
Douglas Gregor44c181a2010-07-23 00:33:23 +00002393 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002394 bool CompleteTranslationUnit
2395 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002396 bool CacheCodeCompetionResults
2397 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002398 bool CXXPrecompilePreamble
2399 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2400 bool CXXChainedPCH
2401 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002402
Douglas Gregor5352ac02010-01-28 00:27:43 +00002403 // Configure the diagnostics.
2404 DiagnosticOptions DiagOpts;
Ted Kremenek25a11e12011-03-22 01:15:24 +00002405 llvm::IntrusiveRefCntPtr<Diagnostic>
2406 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2407 command_line_args));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002408
Ted Kremenek25a11e12011-03-22 01:15:24 +00002409 // Recover resources if we crash before exiting this function.
2410 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2411 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2412 DiagCleanup(Diags.getPtr());
2413
2414 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2415 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2416
2417 // Recover resources if we crash before exiting this function.
2418 llvm::CrashRecoveryContextCleanupRegistrar<
2419 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2420
Douglas Gregor4db64a42010-01-23 00:14:00 +00002421 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002422 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002423 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002424 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002425 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2426 Buffer));
Douglas Gregor4db64a42010-01-23 00:14:00 +00002427 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002428
Ted Kremenek25a11e12011-03-22 01:15:24 +00002429 llvm::OwningPtr<std::vector<const char *> >
2430 Args(new std::vector<const char*>());
2431
2432 // Recover resources if we crash before exiting this method.
2433 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2434 ArgsCleanup(Args.get());
2435
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002436 // Since the Clang C library is primarily used by batch tools dealing with
2437 // (often very broken) source code, where spell-checking can have a
2438 // significant negative impact on performance (particularly when
2439 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002440 // Only do this if we haven't found a spell-checking-related argument.
2441 bool FoundSpellCheckingArgument = false;
2442 for (int I = 0; I != num_command_line_args; ++I) {
2443 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2444 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2445 FoundSpellCheckingArgument = true;
2446 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002447 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002448 }
2449 if (!FoundSpellCheckingArgument)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002450 Args->push_back("-fno-spell-checking");
Douglas Gregorb10daed2010-10-11 16:52:23 +00002451
Ted Kremenek25a11e12011-03-22 01:15:24 +00002452 Args->insert(Args->end(), command_line_args,
2453 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002454
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002455 // The 'source_filename' argument is optional. If the caller does not
2456 // specify it then it is assumed that the source file is specified
2457 // in the actual argument list.
2458 // Put the source file after command_line_args otherwise if '-x' flag is
2459 // present it will be unused.
2460 if (source_filename)
Ted Kremenek25a11e12011-03-22 01:15:24 +00002461 Args->push_back(source_filename);
Argyrios Kyrtzidisc8429552011-03-20 18:17:52 +00002462
Douglas Gregor44c181a2010-07-23 00:33:23 +00002463 // Do we need the detailed preprocessing record?
2464 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek25a11e12011-03-22 01:15:24 +00002465 Args->push_back("-Xclang");
2466 Args->push_back("-detailed-preprocessing-record");
Douglas Gregor44c181a2010-07-23 00:33:23 +00002467 }
2468
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002469 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002470 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek4ee99262011-03-22 20:16:19 +00002471 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2472 /* vector::data() not portable */,
2473 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002474 Diags,
2475 CXXIdx->getClangResourcesPath(),
2476 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002477 /*CaptureDiagnostics=*/true,
Ted Kremenek4ee99262011-03-22 20:16:19 +00002478 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek25a11e12011-03-22 01:15:24 +00002479 RemappedFiles->size(),
Argyrios Kyrtzidis299a4a92011-03-08 23:35:24 +00002480 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002481 PrecompilePreamble,
2482 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002483 CacheCodeCompetionResults,
2484 CXXPrecompilePreamble,
2485 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002486
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002487 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002488 // Make sure to check that 'Unit' is non-NULL.
2489 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2490 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2491 DEnd = Unit->stored_diag_end();
2492 D != DEnd; ++D) {
2493 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2494 CXString Msg = clang_formatDiagnostic(&Diag,
2495 clang_defaultDiagnosticDisplayOptions());
2496 fprintf(stderr, "%s\n", clang_getCString(Msg));
2497 clang_disposeString(Msg);
2498 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002499#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002500 // On Windows, force a flush, since there may be multiple copies of
2501 // stderr and stdout in the file system, all with different buffers
2502 // but writing to the same device.
2503 fflush(stderr);
2504#endif
2505 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002506 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002507
Ted Kremeneka60ed472010-11-16 08:15:36 +00002508 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002509}
2510CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2511 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002512 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002513 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002514 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002515 unsigned num_unsaved_files,
2516 unsigned options) {
2517 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002518 num_command_line_args, unsaved_files,
2519 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002520 llvm::CrashRecoveryContext CRC;
2521
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002522 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002523 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2524 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2525 fprintf(stderr, " 'command_line_args' : [");
2526 for (int i = 0; i != num_command_line_args; ++i) {
2527 if (i)
2528 fprintf(stderr, ", ");
2529 fprintf(stderr, "'%s'", command_line_args[i]);
2530 }
2531 fprintf(stderr, "],\n");
2532 fprintf(stderr, " 'unsaved_files' : [");
2533 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2534 if (i)
2535 fprintf(stderr, ", ");
2536 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2537 unsaved_files[i].Length);
2538 }
2539 fprintf(stderr, "],\n");
2540 fprintf(stderr, " 'options' : %d,\n", options);
2541 fprintf(stderr, "}\n");
2542
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002543 return 0;
2544 }
2545
2546 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002547}
2548
Douglas Gregor19998442010-08-13 15:35:05 +00002549unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2550 return CXSaveTranslationUnit_None;
2551}
2552
2553int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2554 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002555 if (!TU)
2556 return 1;
2557
Ted Kremeneka60ed472010-11-16 08:15:36 +00002558 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002559}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002560
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002561void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002562 if (CTUnit) {
2563 // If the translation unit has been marked as unsafe to free, just discard
2564 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002565 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002566 return;
2567
Ted Kremeneka60ed472010-11-16 08:15:36 +00002568 delete static_cast<ASTUnit *>(CTUnit->TUData);
2569 disposeCXStringPool(CTUnit->StringPool);
2570 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002571 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002572}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002573
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002574unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2575 return CXReparse_None;
2576}
2577
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002578struct ReparseTranslationUnitInfo {
2579 CXTranslationUnit TU;
2580 unsigned num_unsaved_files;
2581 struct CXUnsavedFile *unsaved_files;
2582 unsigned options;
2583 int result;
2584};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002585
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002586static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002587 ReparseTranslationUnitInfo *RTUI =
2588 static_cast<ReparseTranslationUnitInfo*>(UserData);
2589 CXTranslationUnit TU = RTUI->TU;
2590 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2591 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2592 unsigned options = RTUI->options;
2593 (void) options;
2594 RTUI->result = 1;
2595
Douglas Gregorabc563f2010-07-19 21:46:24 +00002596 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002597 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002598
Ted Kremeneka60ed472010-11-16 08:15:36 +00002599 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002600 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002601
Ted Kremenek25a11e12011-03-22 01:15:24 +00002602 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2603 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2604
2605 // Recover resources if we crash before exiting this function.
2606 llvm::CrashRecoveryContextCleanupRegistrar<
2607 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2608
Douglas Gregorabc563f2010-07-19 21:46:24 +00002609 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2610 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2611 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002612 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek25a11e12011-03-22 01:15:24 +00002613 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2614 Buffer));
Douglas Gregorabc563f2010-07-19 21:46:24 +00002615 }
2616
Ted Kremenek4ee99262011-03-22 20:16:19 +00002617 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2618 RemappedFiles->size()))
Douglas Gregor593b0c12010-09-23 18:47:53 +00002619 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002620}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002621
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002622int clang_reparseTranslationUnit(CXTranslationUnit TU,
2623 unsigned num_unsaved_files,
2624 struct CXUnsavedFile *unsaved_files,
2625 unsigned options) {
2626 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2627 options, 0 };
2628 llvm::CrashRecoveryContext CRC;
2629
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002630 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002631 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002632 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002633 return 1;
2634 }
2635
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002636
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002637 return RTUI.result;
2638}
2639
Douglas Gregordf95a132010-08-09 20:45:32 +00002640
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002641CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002642 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002643 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002644
Ted Kremeneka60ed472010-11-16 08:15:36 +00002645 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002646 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002647}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002648
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002649CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002650 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002651 return Result;
2652}
2653
Ted Kremenekfb480492010-01-13 21:46:36 +00002654} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002655
Ted Kremenekfb480492010-01-13 21:46:36 +00002656//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002657// CXSourceLocation and CXSourceRange Operations.
2658//===----------------------------------------------------------------------===//
2659
Douglas Gregorb9790342010-01-22 21:44:22 +00002660extern "C" {
2661CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002662 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002663 return Result;
2664}
2665
2666unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002667 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2668 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2669 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002670}
2671
2672CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2673 CXFile file,
2674 unsigned line,
2675 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002676 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002677 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002678
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002679 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002680 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002681 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002682 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002683 = CXXUnit->getSourceManager().getLocation(File, line, column);
2684 if (SLoc.isInvalid()) {
2685 if (Logging)
2686 llvm::errs() << "clang_getLocation(\"" << File->getName()
2687 << "\", " << line << ", " << column << ") = invalid\n";
2688 return clang_getNullLocation();
2689 }
2690
2691 if (Logging)
2692 llvm::errs() << "clang_getLocation(\"" << File->getName()
2693 << "\", " << line << ", " << column << ") = "
2694 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002695
2696 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2697}
2698
2699CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2700 CXFile file,
2701 unsigned offset) {
2702 if (!tu || !file)
2703 return clang_getNullLocation();
2704
Ted Kremeneka60ed472010-11-16 08:15:36 +00002705 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002706 SourceLocation Start
2707 = CXXUnit->getSourceManager().getLocation(
2708 static_cast<const FileEntry *>(file),
2709 1, 1);
2710 if (Start.isInvalid()) return clang_getNullLocation();
2711
2712 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2713
2714 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002715
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002716 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002717}
2718
Douglas Gregor5352ac02010-01-28 00:27:43 +00002719CXSourceRange clang_getNullRange() {
2720 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2721 return Result;
2722}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002723
Douglas Gregor5352ac02010-01-28 00:27:43 +00002724CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2725 if (begin.ptr_data[0] != end.ptr_data[0] ||
2726 begin.ptr_data[1] != end.ptr_data[1])
2727 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002728
2729 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002730 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002731 return Result;
2732}
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002733} // end: extern "C"
Douglas Gregorb9790342010-01-22 21:44:22 +00002734
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002735static void createNullLocation(CXFile *file, unsigned *line,
2736 unsigned *column, unsigned *offset) {
2737 if (file)
2738 *file = 0;
2739 if (line)
2740 *line = 0;
2741 if (column)
2742 *column = 0;
2743 if (offset)
2744 *offset = 0;
2745 return;
2746}
2747
2748extern "C" {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002749void clang_getInstantiationLocation(CXSourceLocation location,
2750 CXFile *file,
2751 unsigned *line,
2752 unsigned *column,
2753 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002754 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2755
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002756 if (!location.ptr_data[0] || Loc.isInvalid()) {
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002757 createNullLocation(file, line, column, offset);
Douglas Gregor46766dc2010-01-26 19:19:08 +00002758 return;
2759 }
2760
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002761 const SourceManager &SM =
2762 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002763 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002764
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002765 // Check that the FileID is invalid on the instantiation location.
2766 // This can manifest in invalid code.
2767 FileID fileID = SM.getFileID(InstLoc);
2768 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID);
2769 if (!sloc.isFile()) {
2770 createNullLocation(file, line, column, offset);
2771 return;
2772 }
2773
Douglas Gregor1db19de2010-01-19 21:36:55 +00002774 if (file)
Ted Kremenek9d5a1652011-03-23 02:16:44 +00002775 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002776 if (line)
2777 *line = SM.getInstantiationLineNumber(InstLoc);
2778 if (column)
2779 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002780 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002781 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002782}
2783
Douglas Gregora9b06d42010-11-09 06:24:54 +00002784void clang_getSpellingLocation(CXSourceLocation location,
2785 CXFile *file,
2786 unsigned *line,
2787 unsigned *column,
2788 unsigned *offset) {
2789 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2790
2791 if (!location.ptr_data[0] || Loc.isInvalid()) {
2792 if (file)
2793 *file = 0;
2794 if (line)
2795 *line = 0;
2796 if (column)
2797 *column = 0;
2798 if (offset)
2799 *offset = 0;
2800 return;
2801 }
2802
2803 const SourceManager &SM =
2804 *static_cast<const SourceManager*>(location.ptr_data[0]);
2805 SourceLocation SpellLoc = Loc;
2806 if (SpellLoc.isMacroID()) {
2807 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2808 if (SimpleSpellingLoc.isFileID() &&
2809 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2810 SpellLoc = SimpleSpellingLoc;
2811 else
2812 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2813 }
2814
2815 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2816 FileID FID = LocInfo.first;
2817 unsigned FileOffset = LocInfo.second;
2818
2819 if (file)
2820 *file = (void *)SM.getFileEntryForID(FID);
2821 if (line)
2822 *line = SM.getLineNumber(FID, FileOffset);
2823 if (column)
2824 *column = SM.getColumnNumber(FID, FileOffset);
2825 if (offset)
2826 *offset = FileOffset;
2827}
2828
Douglas Gregor1db19de2010-01-19 21:36:55 +00002829CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002830 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002831 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002832 return Result;
2833}
2834
2835CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002836 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002837 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002838 return Result;
2839}
2840
Douglas Gregorb9790342010-01-22 21:44:22 +00002841} // end: extern "C"
2842
Douglas Gregor1db19de2010-01-19 21:36:55 +00002843//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002844// CXFile Operations.
2845//===----------------------------------------------------------------------===//
2846
2847extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002848CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002849 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002850 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002851
Steve Naroff88145032009-10-27 14:35:18 +00002852 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002853 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002854}
2855
2856time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002857 if (!SFile)
2858 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002859
Steve Naroff88145032009-10-27 14:35:18 +00002860 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2861 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002862}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002863
Douglas Gregorb9790342010-01-22 21:44:22 +00002864CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2865 if (!tu)
2866 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002867
Ted Kremeneka60ed472010-11-16 08:15:36 +00002868 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002869
Douglas Gregorb9790342010-01-22 21:44:22 +00002870 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002871 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002872}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002873
Ted Kremenekfb480492010-01-13 21:46:36 +00002874} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002875
Ted Kremenekfb480492010-01-13 21:46:36 +00002876//===----------------------------------------------------------------------===//
2877// CXCursor Operations.
2878//===----------------------------------------------------------------------===//
2879
Ted Kremenekfb480492010-01-13 21:46:36 +00002880static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002881 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2882 return getDeclFromExpr(CE->getSubExpr());
2883
Ted Kremenekfb480492010-01-13 21:46:36 +00002884 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2885 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002886 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2887 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002888 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2889 return ME->getMemberDecl();
2890 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2891 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002892 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002893 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002894
Ted Kremenekfb480492010-01-13 21:46:36 +00002895 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2896 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002897 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2898 if (!CE->isElidable())
2899 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002900 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2901 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002902
Douglas Gregordb1314e2010-10-01 21:11:22 +00002903 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2904 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002905 if (SubstNonTypeTemplateParmPackExpr *NTTP
2906 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2907 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002908 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2909 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2910 isa<ParmVarDecl>(SizeOfPack->getPack()))
2911 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002912
Ted Kremenekfb480492010-01-13 21:46:36 +00002913 return 0;
2914}
2915
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002916static SourceLocation getLocationFromExpr(Expr *E) {
2917 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2918 return /*FIXME:*/Msg->getLeftLoc();
2919 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2920 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002921 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2922 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002923 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2924 return Member->getMemberLoc();
2925 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2926 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002927 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2928 return SizeOfPack->getPackLoc();
2929
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002930 return E->getLocStart();
2931}
2932
Ted Kremenekfb480492010-01-13 21:46:36 +00002933extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002934
2935unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002936 CXCursorVisitor visitor,
2937 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002938 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00002939 getCursorASTUnit(parent)->getMaxPCHLevel(),
2940 false);
Douglas Gregorb1373d02010-01-20 20:59:29 +00002941 return CursorVis.VisitChildren(parent);
2942}
2943
David Chisnall3387c652010-11-03 14:12:26 +00002944#ifndef __has_feature
2945#define __has_feature(x) 0
2946#endif
2947#if __has_feature(blocks)
2948typedef enum CXChildVisitResult
2949 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2950
2951static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2952 CXClientData client_data) {
2953 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2954 return block(cursor, parent);
2955}
2956#else
2957// If we are compiled with a compiler that doesn't have native blocks support,
2958// define and call the block manually, so the
2959typedef struct _CXChildVisitResult
2960{
2961 void *isa;
2962 int flags;
2963 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002964 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2965 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002966} *CXCursorVisitorBlock;
2967
2968static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2969 CXClientData client_data) {
2970 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2971 return block->invoke(block, cursor, parent);
2972}
2973#endif
2974
2975
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002976unsigned clang_visitChildrenWithBlock(CXCursor parent,
2977 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002978 return clang_visitChildren(parent, visitWithBlock, block);
2979}
2980
Douglas Gregor78205d42010-01-20 21:45:58 +00002981static CXString getDeclSpelling(Decl *D) {
2982 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00002983 if (!ND) {
2984 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2985 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2986 return createCXString(Property->getIdentifier()->getName());
2987
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002988 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00002989 }
2990
Douglas Gregor78205d42010-01-20 21:45:58 +00002991 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002992 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002993
Douglas Gregor78205d42010-01-20 21:45:58 +00002994 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2995 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2996 // and returns different names. NamedDecl returns the class name and
2997 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002998 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002999
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003000 if (isa<UsingDirectiveDecl>(D))
3001 return createCXString("");
3002
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00003003 llvm::SmallString<1024> S;
3004 llvm::raw_svector_ostream os(S);
3005 ND->printName(os);
3006
3007 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00003008}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003009
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003010CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003011 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003012 return clang_getTranslationUnitSpelling(
3013 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003014
Steve Narofff334b4e2009-09-02 18:26:48 +00003015 if (clang_isReference(C.kind)) {
3016 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00003017 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00003018 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003019 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003020 }
3021 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00003022 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003023 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003024 }
3025 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00003026 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00003027 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003028 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00003029 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00003030 case CXCursor_CXXBaseSpecifier: {
3031 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3032 return createCXString(B->getType().getAsString());
3033 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003034 case CXCursor_TypeRef: {
3035 TypeDecl *Type = getCursorTypeRef(C).first;
3036 assert(Type && "Missing type decl");
3037
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003038 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3039 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003040 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003041 case CXCursor_TemplateRef: {
3042 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00003043 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003044
3045 return createCXString(Template->getNameAsString());
3046 }
Douglas Gregor69319002010-08-31 23:48:11 +00003047
3048 case CXCursor_NamespaceRef: {
3049 NamedDecl *NS = getCursorNamespaceRef(C).first;
3050 assert(NS && "Missing namespace decl");
3051
3052 return createCXString(NS->getNameAsString());
3053 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003054
Douglas Gregora67e03f2010-09-09 21:42:20 +00003055 case CXCursor_MemberRef: {
3056 FieldDecl *Field = getCursorMemberRef(C).first;
3057 assert(Field && "Missing member decl");
3058
3059 return createCXString(Field->getNameAsString());
3060 }
3061
Douglas Gregor36897b02010-09-10 00:22:18 +00003062 case CXCursor_LabelRef: {
3063 LabelStmt *Label = getCursorLabelRef(C).first;
3064 assert(Label && "Missing label");
3065
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003066 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003067 }
3068
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003069 case CXCursor_OverloadedDeclRef: {
3070 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3071 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3072 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3073 return createCXString(ND->getNameAsString());
3074 return createCXString("");
3075 }
3076 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3077 return createCXString(E->getName().getAsString());
3078 OverloadedTemplateStorage *Ovl
3079 = Storage.get<OverloadedTemplateStorage*>();
3080 if (Ovl->size() == 0)
3081 return createCXString("");
3082 return createCXString((*Ovl->begin())->getNameAsString());
3083 }
3084
Daniel Dunbaracca7252009-11-30 20:42:49 +00003085 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003086 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003087 }
3088 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003089
3090 if (clang_isExpression(C.kind)) {
3091 Decl *D = getDeclFromExpr(getCursorExpr(C));
3092 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003093 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003094 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003095 }
3096
Douglas Gregor36897b02010-09-10 00:22:18 +00003097 if (clang_isStatement(C.kind)) {
3098 Stmt *S = getCursorStmt(C);
3099 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003100 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003101
3102 return createCXString("");
3103 }
3104
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003105 if (C.kind == CXCursor_MacroInstantiation)
3106 return createCXString(getCursorMacroInstantiation(C)->getName()
3107 ->getNameStart());
3108
Douglas Gregor572feb22010-03-18 18:04:21 +00003109 if (C.kind == CXCursor_MacroDefinition)
3110 return createCXString(getCursorMacroDefinition(C)->getName()
3111 ->getNameStart());
3112
Douglas Gregorecdcb882010-10-20 22:00:55 +00003113 if (C.kind == CXCursor_InclusionDirective)
3114 return createCXString(getCursorInclusionDirective(C)->getFileName());
3115
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003116 if (clang_isDeclaration(C.kind))
3117 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003118
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003119 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003120}
3121
Douglas Gregor358559d2010-10-02 22:49:11 +00003122CXString clang_getCursorDisplayName(CXCursor C) {
3123 if (!clang_isDeclaration(C.kind))
3124 return clang_getCursorSpelling(C);
3125
3126 Decl *D = getCursorDecl(C);
3127 if (!D)
3128 return createCXString("");
3129
3130 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3131 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3132 D = FunTmpl->getTemplatedDecl();
3133
3134 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3135 llvm::SmallString<64> Str;
3136 llvm::raw_svector_ostream OS(Str);
3137 OS << Function->getNameAsString();
3138 if (Function->getPrimaryTemplate())
3139 OS << "<>";
3140 OS << "(";
3141 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3142 if (I)
3143 OS << ", ";
3144 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3145 }
3146
3147 if (Function->isVariadic()) {
3148 if (Function->getNumParams())
3149 OS << ", ";
3150 OS << "...";
3151 }
3152 OS << ")";
3153 return createCXString(OS.str());
3154 }
3155
3156 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3157 llvm::SmallString<64> Str;
3158 llvm::raw_svector_ostream OS(Str);
3159 OS << ClassTemplate->getNameAsString();
3160 OS << "<";
3161 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3162 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3163 if (I)
3164 OS << ", ";
3165
3166 NamedDecl *Param = Params->getParam(I);
3167 if (Param->getIdentifier()) {
3168 OS << Param->getIdentifier()->getName();
3169 continue;
3170 }
3171
3172 // There is no parameter name, which makes this tricky. Try to come up
3173 // with something useful that isn't too long.
3174 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3175 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3176 else if (NonTypeTemplateParmDecl *NTTP
3177 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3178 OS << NTTP->getType().getAsString(Policy);
3179 else
3180 OS << "template<...> class";
3181 }
3182
3183 OS << ">";
3184 return createCXString(OS.str());
3185 }
3186
3187 if (ClassTemplateSpecializationDecl *ClassSpec
3188 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3189 // If the type was explicitly written, use that.
3190 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3191 return createCXString(TSInfo->getType().getAsString(Policy));
3192
3193 llvm::SmallString<64> Str;
3194 llvm::raw_svector_ostream OS(Str);
3195 OS << ClassSpec->getNameAsString();
3196 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003197 ClassSpec->getTemplateArgs().data(),
3198 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003199 Policy);
3200 return createCXString(OS.str());
3201 }
3202
3203 return clang_getCursorSpelling(C);
3204}
3205
Ted Kremeneke68fff62010-02-17 00:41:32 +00003206CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003207 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003208 case CXCursor_FunctionDecl:
3209 return createCXString("FunctionDecl");
3210 case CXCursor_TypedefDecl:
3211 return createCXString("TypedefDecl");
3212 case CXCursor_EnumDecl:
3213 return createCXString("EnumDecl");
3214 case CXCursor_EnumConstantDecl:
3215 return createCXString("EnumConstantDecl");
3216 case CXCursor_StructDecl:
3217 return createCXString("StructDecl");
3218 case CXCursor_UnionDecl:
3219 return createCXString("UnionDecl");
3220 case CXCursor_ClassDecl:
3221 return createCXString("ClassDecl");
3222 case CXCursor_FieldDecl:
3223 return createCXString("FieldDecl");
3224 case CXCursor_VarDecl:
3225 return createCXString("VarDecl");
3226 case CXCursor_ParmDecl:
3227 return createCXString("ParmDecl");
3228 case CXCursor_ObjCInterfaceDecl:
3229 return createCXString("ObjCInterfaceDecl");
3230 case CXCursor_ObjCCategoryDecl:
3231 return createCXString("ObjCCategoryDecl");
3232 case CXCursor_ObjCProtocolDecl:
3233 return createCXString("ObjCProtocolDecl");
3234 case CXCursor_ObjCPropertyDecl:
3235 return createCXString("ObjCPropertyDecl");
3236 case CXCursor_ObjCIvarDecl:
3237 return createCXString("ObjCIvarDecl");
3238 case CXCursor_ObjCInstanceMethodDecl:
3239 return createCXString("ObjCInstanceMethodDecl");
3240 case CXCursor_ObjCClassMethodDecl:
3241 return createCXString("ObjCClassMethodDecl");
3242 case CXCursor_ObjCImplementationDecl:
3243 return createCXString("ObjCImplementationDecl");
3244 case CXCursor_ObjCCategoryImplDecl:
3245 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003246 case CXCursor_CXXMethod:
3247 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003248 case CXCursor_UnexposedDecl:
3249 return createCXString("UnexposedDecl");
3250 case CXCursor_ObjCSuperClassRef:
3251 return createCXString("ObjCSuperClassRef");
3252 case CXCursor_ObjCProtocolRef:
3253 return createCXString("ObjCProtocolRef");
3254 case CXCursor_ObjCClassRef:
3255 return createCXString("ObjCClassRef");
3256 case CXCursor_TypeRef:
3257 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003258 case CXCursor_TemplateRef:
3259 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003260 case CXCursor_NamespaceRef:
3261 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003262 case CXCursor_MemberRef:
3263 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003264 case CXCursor_LabelRef:
3265 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003266 case CXCursor_OverloadedDeclRef:
3267 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003268 case CXCursor_UnexposedExpr:
3269 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003270 case CXCursor_BlockExpr:
3271 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003272 case CXCursor_DeclRefExpr:
3273 return createCXString("DeclRefExpr");
3274 case CXCursor_MemberRefExpr:
3275 return createCXString("MemberRefExpr");
3276 case CXCursor_CallExpr:
3277 return createCXString("CallExpr");
3278 case CXCursor_ObjCMessageExpr:
3279 return createCXString("ObjCMessageExpr");
3280 case CXCursor_UnexposedStmt:
3281 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003282 case CXCursor_LabelStmt:
3283 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003284 case CXCursor_InvalidFile:
3285 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003286 case CXCursor_InvalidCode:
3287 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003288 case CXCursor_NoDeclFound:
3289 return createCXString("NoDeclFound");
3290 case CXCursor_NotImplemented:
3291 return createCXString("NotImplemented");
3292 case CXCursor_TranslationUnit:
3293 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003294 case CXCursor_UnexposedAttr:
3295 return createCXString("UnexposedAttr");
3296 case CXCursor_IBActionAttr:
3297 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003298 case CXCursor_IBOutletAttr:
3299 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003300 case CXCursor_IBOutletCollectionAttr:
3301 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003302 case CXCursor_PreprocessingDirective:
3303 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003304 case CXCursor_MacroDefinition:
3305 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003306 case CXCursor_MacroInstantiation:
3307 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003308 case CXCursor_InclusionDirective:
3309 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003310 case CXCursor_Namespace:
3311 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003312 case CXCursor_LinkageSpec:
3313 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003314 case CXCursor_CXXBaseSpecifier:
3315 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003316 case CXCursor_Constructor:
3317 return createCXString("CXXConstructor");
3318 case CXCursor_Destructor:
3319 return createCXString("CXXDestructor");
3320 case CXCursor_ConversionFunction:
3321 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003322 case CXCursor_TemplateTypeParameter:
3323 return createCXString("TemplateTypeParameter");
3324 case CXCursor_NonTypeTemplateParameter:
3325 return createCXString("NonTypeTemplateParameter");
3326 case CXCursor_TemplateTemplateParameter:
3327 return createCXString("TemplateTemplateParameter");
3328 case CXCursor_FunctionTemplate:
3329 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003330 case CXCursor_ClassTemplate:
3331 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003332 case CXCursor_ClassTemplatePartialSpecialization:
3333 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003334 case CXCursor_NamespaceAlias:
3335 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003336 case CXCursor_UsingDirective:
3337 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003338 case CXCursor_UsingDeclaration:
3339 return createCXString("UsingDeclaration");
Steve Naroff89922f82009-08-31 00:59:03 +00003340 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003341
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003342 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003343 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003344}
Steve Naroff89922f82009-08-31 00:59:03 +00003345
Ted Kremeneke68fff62010-02-17 00:41:32 +00003346enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3347 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003348 CXClientData client_data) {
3349 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003350
3351 // If our current best cursor is the construction of a temporary object,
3352 // don't replace that cursor with a type reference, because we want
3353 // clang_getCursor() to point at the constructor.
3354 if (clang_isExpression(BestCursor->kind) &&
3355 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3356 cursor.kind == CXCursor_TypeRef)
3357 return CXChildVisit_Recurse;
3358
Douglas Gregor85fe1562010-12-10 07:23:11 +00003359 // Don't override a preprocessing cursor with another preprocessing
3360 // cursor; we want the outermost preprocessing cursor.
3361 if (clang_isPreprocessing(cursor.kind) &&
3362 clang_isPreprocessing(BestCursor->kind))
3363 return CXChildVisit_Recurse;
3364
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003365 *BestCursor = cursor;
3366 return CXChildVisit_Recurse;
3367}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003368
Douglas Gregorb9790342010-01-22 21:44:22 +00003369CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3370 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003371 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003372
Ted Kremeneka60ed472010-11-16 08:15:36 +00003373 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003374 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3375
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003376 // Translate the given source location to make it point at the beginning of
3377 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003378 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003379
3380 // Guard against an invalid SourceLocation, or we may assert in one
3381 // of the following calls.
3382 if (SLoc.isInvalid())
3383 return clang_getNullCursor();
3384
Douglas Gregor40749ee2010-11-03 00:35:38 +00003385 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003386 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3387 CXXUnit->getASTContext().getLangOptions());
3388
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003389 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3390 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003391 // FIXME: Would be great to have a "hint" cursor, then walk from that
3392 // hint cursor upward until we find a cursor whose source range encloses
3393 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003394 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3395 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00003396 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003397 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003398 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003399
3400 if (Logging) {
3401 CXFile SearchFile;
3402 unsigned SearchLine, SearchColumn;
3403 CXFile ResultFile;
3404 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003405 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3406 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003407 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3408
3409 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3410 0);
3411 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3412 &ResultColumn, 0);
3413 SearchFileName = clang_getFileName(SearchFile);
3414 ResultFileName = clang_getFileName(ResultFile);
3415 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003416 USR = clang_getCursorUSR(Result);
3417 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003418 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3419 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003420 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3421 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003422 clang_disposeString(SearchFileName);
3423 clang_disposeString(ResultFileName);
3424 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003425 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003426
3427 CXCursor Definition = clang_getCursorDefinition(Result);
3428 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3429 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3430 CXString DefinitionKindSpelling
3431 = clang_getCursorKindSpelling(Definition.kind);
3432 CXFile DefinitionFile;
3433 unsigned DefinitionLine, DefinitionColumn;
3434 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3435 &DefinitionLine, &DefinitionColumn, 0);
3436 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3437 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3438 clang_getCString(DefinitionKindSpelling),
3439 clang_getCString(DefinitionFileName),
3440 DefinitionLine, DefinitionColumn);
3441 clang_disposeString(DefinitionFileName);
3442 clang_disposeString(DefinitionKindSpelling);
3443 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003444 }
3445
Ted Kremeneke68fff62010-02-17 00:41:32 +00003446 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003447}
3448
Ted Kremenek73885552009-11-17 19:28:59 +00003449CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003450 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003451}
3452
3453unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003454 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003455}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003456
Douglas Gregor9ce55842010-11-20 00:09:34 +00003457unsigned clang_hashCursor(CXCursor C) {
3458 unsigned Index = 0;
3459 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3460 Index = 1;
3461
3462 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3463 std::make_pair(C.kind, C.data[Index]));
3464}
3465
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003466unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003467 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3468}
3469
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003470unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003471 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3472}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003473
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003474unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003475 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3476}
3477
Douglas Gregor97b98722010-01-19 23:20:36 +00003478unsigned clang_isExpression(enum CXCursorKind K) {
3479 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3480}
3481
3482unsigned clang_isStatement(enum CXCursorKind K) {
3483 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3484}
3485
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003486unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3487 return K == CXCursor_TranslationUnit;
3488}
3489
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003490unsigned clang_isPreprocessing(enum CXCursorKind K) {
3491 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3492}
3493
Ted Kremenekad6eff62010-03-08 21:17:29 +00003494unsigned clang_isUnexposed(enum CXCursorKind K) {
3495 switch (K) {
3496 case CXCursor_UnexposedDecl:
3497 case CXCursor_UnexposedExpr:
3498 case CXCursor_UnexposedStmt:
3499 case CXCursor_UnexposedAttr:
3500 return true;
3501 default:
3502 return false;
3503 }
3504}
3505
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003506CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003507 return C.kind;
3508}
3509
Douglas Gregor98258af2010-01-18 22:46:11 +00003510CXSourceLocation clang_getCursorLocation(CXCursor C) {
3511 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003512 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003513 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003514 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3515 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003516 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003517 }
3518
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003519 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003520 std::pair<ObjCProtocolDecl *, SourceLocation> P
3521 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003522 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003523 }
3524
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003525 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003526 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3527 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003528 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003529 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003530
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003531 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003532 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003533 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003534 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003535
3536 case CXCursor_TemplateRef: {
3537 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3538 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3539 }
3540
Douglas Gregor69319002010-08-31 23:48:11 +00003541 case CXCursor_NamespaceRef: {
3542 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3543 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3544 }
3545
Douglas Gregora67e03f2010-09-09 21:42:20 +00003546 case CXCursor_MemberRef: {
3547 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3548 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3549 }
3550
Ted Kremenek3064ef92010-08-27 21:34:58 +00003551 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003552 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3553 if (!BaseSpec)
3554 return clang_getNullLocation();
3555
3556 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3557 return cxloc::translateSourceLocation(getCursorContext(C),
3558 TSInfo->getTypeLoc().getBeginLoc());
3559
3560 return cxloc::translateSourceLocation(getCursorContext(C),
3561 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003562 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003563
Douglas Gregor36897b02010-09-10 00:22:18 +00003564 case CXCursor_LabelRef: {
3565 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3566 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3567 }
3568
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003569 case CXCursor_OverloadedDeclRef:
3570 return cxloc::translateSourceLocation(getCursorContext(C),
3571 getCursorOverloadedDeclRef(C).second);
3572
Douglas Gregorf46034a2010-01-18 23:41:10 +00003573 default:
3574 // FIXME: Need a way to enumerate all non-reference cases.
3575 llvm_unreachable("Missed a reference kind");
3576 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003577 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003578
3579 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003580 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003581 getLocationFromExpr(getCursorExpr(C)));
3582
Douglas Gregor36897b02010-09-10 00:22:18 +00003583 if (clang_isStatement(C.kind))
3584 return cxloc::translateSourceLocation(getCursorContext(C),
3585 getCursorStmt(C)->getLocStart());
3586
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003587 if (C.kind == CXCursor_PreprocessingDirective) {
3588 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3589 return cxloc::translateSourceLocation(getCursorContext(C), L);
3590 }
Douglas Gregor48072312010-03-18 15:23:44 +00003591
3592 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003593 SourceLocation L
3594 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003595 return cxloc::translateSourceLocation(getCursorContext(C), L);
3596 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003597
3598 if (C.kind == CXCursor_MacroDefinition) {
3599 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3600 return cxloc::translateSourceLocation(getCursorContext(C), L);
3601 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003602
3603 if (C.kind == CXCursor_InclusionDirective) {
3604 SourceLocation L
3605 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3606 return cxloc::translateSourceLocation(getCursorContext(C), L);
3607 }
3608
Ted Kremenek9a700d22010-05-12 06:16:13 +00003609 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003610 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003611
Douglas Gregorf46034a2010-01-18 23:41:10 +00003612 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003613 SourceLocation Loc = D->getLocation();
3614 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3615 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003616 // FIXME: Multiple variables declared in a single declaration
3617 // currently lack the information needed to correctly determine their
3618 // ranges when accounting for the type-specifier. We use context
3619 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3620 // and if so, whether it is the first decl.
3621 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3622 if (!cxcursor::isFirstInDeclGroup(C))
3623 Loc = VD->getLocation();
3624 }
3625
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003626 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003627}
Douglas Gregora7bde202010-01-19 00:34:46 +00003628
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003629} // end extern "C"
3630
3631static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003632 if (clang_isReference(C.kind)) {
3633 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003634 case CXCursor_ObjCSuperClassRef:
3635 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003636
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003637 case CXCursor_ObjCProtocolRef:
3638 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003639
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003640 case CXCursor_ObjCClassRef:
3641 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003642
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003643 case CXCursor_TypeRef:
3644 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003645
3646 case CXCursor_TemplateRef:
3647 return getCursorTemplateRef(C).second;
3648
Douglas Gregor69319002010-08-31 23:48:11 +00003649 case CXCursor_NamespaceRef:
3650 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003651
3652 case CXCursor_MemberRef:
3653 return getCursorMemberRef(C).second;
3654
Ted Kremenek3064ef92010-08-27 21:34:58 +00003655 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003656 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003657
Douglas Gregor36897b02010-09-10 00:22:18 +00003658 case CXCursor_LabelRef:
3659 return getCursorLabelRef(C).second;
3660
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003661 case CXCursor_OverloadedDeclRef:
3662 return getCursorOverloadedDeclRef(C).second;
3663
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003664 default:
3665 // FIXME: Need a way to enumerate all non-reference cases.
3666 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003667 }
3668 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003669
3670 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003671 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003672
3673 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003674 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003675
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003676 if (C.kind == CXCursor_PreprocessingDirective)
3677 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003678
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003679 if (C.kind == CXCursor_MacroInstantiation)
3680 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003681
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003682 if (C.kind == CXCursor_MacroDefinition)
3683 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003684
3685 if (C.kind == CXCursor_InclusionDirective)
3686 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3687
Ted Kremenek007a7c92010-11-01 23:26:51 +00003688 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3689 Decl *D = cxcursor::getCursorDecl(C);
3690 SourceRange R = D->getSourceRange();
3691 // FIXME: Multiple variables declared in a single declaration
3692 // currently lack the information needed to correctly determine their
3693 // ranges when accounting for the type-specifier. We use context
3694 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3695 // and if so, whether it is the first decl.
3696 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3697 if (!cxcursor::isFirstInDeclGroup(C))
3698 R.setBegin(VD->getLocation());
3699 }
3700 return R;
3701 }
Douglas Gregor66537982010-11-17 17:14:07 +00003702 return SourceRange();
3703}
3704
3705/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3706/// the decl-specifier-seq for declarations.
3707static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3708 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3709 Decl *D = cxcursor::getCursorDecl(C);
3710 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003711
Douglas Gregor2494dd02011-03-01 01:34:45 +00003712 // Adjust the start of the location for declarations preceded by
3713 // declaration specifiers.
3714 SourceLocation StartLoc;
3715 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3716 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3717 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3718 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3719 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3720 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3721 }
3722
3723 if (StartLoc.isValid() && R.getBegin().isValid() &&
3724 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3725 R.setBegin(StartLoc);
3726
3727 // FIXME: Multiple variables declared in a single declaration
3728 // currently lack the information needed to correctly determine their
3729 // ranges when accounting for the type-specifier. We use context
3730 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3731 // and if so, whether it is the first decl.
3732 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3733 if (!cxcursor::isFirstInDeclGroup(C))
3734 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003735 }
3736
3737 return R;
3738 }
3739
3740 return getRawCursorExtent(C);
3741}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003742
3743extern "C" {
3744
3745CXSourceRange clang_getCursorExtent(CXCursor C) {
3746 SourceRange R = getRawCursorExtent(C);
3747 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003748 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003749
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003750 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003751}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003752
3753CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003754 if (clang_isInvalid(C.kind))
3755 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003756
Ted Kremeneka60ed472010-11-16 08:15:36 +00003757 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003758 if (clang_isDeclaration(C.kind)) {
3759 Decl *D = getCursorDecl(C);
3760 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003761 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003762 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003763 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003764 if (ObjCForwardProtocolDecl *Protocols
3765 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003766 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003767 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3768 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3769 return MakeCXCursor(Property, tu);
3770
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003771 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003772 }
3773
Douglas Gregor97b98722010-01-19 23:20:36 +00003774 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003775 Expr *E = getCursorExpr(C);
3776 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003777 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003778 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003779
3780 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003781 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003782
Douglas Gregor97b98722010-01-19 23:20:36 +00003783 return clang_getNullCursor();
3784 }
3785
Douglas Gregor36897b02010-09-10 00:22:18 +00003786 if (clang_isStatement(C.kind)) {
3787 Stmt *S = getCursorStmt(C);
3788 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek37c2e962011-03-15 23:47:49 +00003789 if (LabelDecl *label = Goto->getLabel())
3790 if (LabelStmt *labelS = label->getStmt())
3791 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003792
3793 return clang_getNullCursor();
3794 }
3795
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003796 if (C.kind == CXCursor_MacroInstantiation) {
3797 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003798 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003799 }
3800
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003801 if (!clang_isReference(C.kind))
3802 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003803
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003804 switch (C.kind) {
3805 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003806 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003807
3808 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003809 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003810
3811 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003812 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003813
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003814 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003815 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003816
3817 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003818 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003819
Douglas Gregor69319002010-08-31 23:48:11 +00003820 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003821 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003822
Douglas Gregora67e03f2010-09-09 21:42:20 +00003823 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003824 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003825
Ted Kremenek3064ef92010-08-27 21:34:58 +00003826 case CXCursor_CXXBaseSpecifier: {
3827 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3828 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003829 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003830 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003831
Douglas Gregor36897b02010-09-10 00:22:18 +00003832 case CXCursor_LabelRef:
3833 // FIXME: We end up faking the "parent" declaration here because we
3834 // don't want to make CXCursor larger.
3835 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003836 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3837 .getTranslationUnitDecl(),
3838 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003839
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003840 case CXCursor_OverloadedDeclRef:
3841 return C;
3842
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003843 default:
3844 // We would prefer to enumerate all non-reference cursor kinds here.
3845 llvm_unreachable("Unhandled reference cursor kind");
3846 break;
3847 }
3848 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003849
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003850 return clang_getNullCursor();
3851}
3852
Douglas Gregorb6998662010-01-19 19:34:47 +00003853CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003854 if (clang_isInvalid(C.kind))
3855 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003856
Ted Kremeneka60ed472010-11-16 08:15:36 +00003857 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003858
Douglas Gregorb6998662010-01-19 19:34:47 +00003859 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003860 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003861 C = clang_getCursorReferenced(C);
3862 WasReference = true;
3863 }
3864
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003865 if (C.kind == CXCursor_MacroInstantiation)
3866 return clang_getCursorReferenced(C);
3867
Douglas Gregorb6998662010-01-19 19:34:47 +00003868 if (!clang_isDeclaration(C.kind))
3869 return clang_getNullCursor();
3870
3871 Decl *D = getCursorDecl(C);
3872 if (!D)
3873 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003874
Douglas Gregorb6998662010-01-19 19:34:47 +00003875 switch (D->getKind()) {
3876 // Declaration kinds that don't really separate the notions of
3877 // declaration and definition.
3878 case Decl::Namespace:
3879 case Decl::Typedef:
3880 case Decl::TemplateTypeParm:
3881 case Decl::EnumConstant:
3882 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003883 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003884 case Decl::ObjCIvar:
3885 case Decl::ObjCAtDefsField:
3886 case Decl::ImplicitParam:
3887 case Decl::ParmVar:
3888 case Decl::NonTypeTemplateParm:
3889 case Decl::TemplateTemplateParm:
3890 case Decl::ObjCCategoryImpl:
3891 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003892 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003893 case Decl::LinkageSpec:
3894 case Decl::ObjCPropertyImpl:
3895 case Decl::FileScopeAsm:
3896 case Decl::StaticAssert:
3897 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003898 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003899 return C;
3900
3901 // Declaration kinds that don't make any sense here, but are
3902 // nonetheless harmless.
3903 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003904 break;
3905
3906 // Declaration kinds for which the definition is not resolvable.
3907 case Decl::UnresolvedUsingTypename:
3908 case Decl::UnresolvedUsingValue:
3909 break;
3910
3911 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003912 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003913 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003914
3915 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003916 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003917
3918 case Decl::Enum:
3919 case Decl::Record:
3920 case Decl::CXXRecord:
3921 case Decl::ClassTemplateSpecialization:
3922 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003923 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003924 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003925 return clang_getNullCursor();
3926
3927 case Decl::Function:
3928 case Decl::CXXMethod:
3929 case Decl::CXXConstructor:
3930 case Decl::CXXDestructor:
3931 case Decl::CXXConversion: {
3932 const FunctionDecl *Def = 0;
3933 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003934 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003935 return clang_getNullCursor();
3936 }
3937
3938 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003939 // Ask the variable if it has a definition.
3940 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003941 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003942 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003943 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003944
Douglas Gregorb6998662010-01-19 19:34:47 +00003945 case Decl::FunctionTemplate: {
3946 const FunctionDecl *Def = 0;
3947 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003948 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003949 return clang_getNullCursor();
3950 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003951
Douglas Gregorb6998662010-01-19 19:34:47 +00003952 case Decl::ClassTemplate: {
3953 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003954 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003955 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003956 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003957 return clang_getNullCursor();
3958 }
3959
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003960 case Decl::Using:
3961 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003962 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003963
3964 case Decl::UsingShadow:
3965 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003966 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003967 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003968
3969 case Decl::ObjCMethod: {
3970 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3971 if (Method->isThisDeclarationADefinition())
3972 return C;
3973
3974 // Dig out the method definition in the associated
3975 // @implementation, if we have it.
3976 // FIXME: The ASTs should make finding the definition easier.
3977 if (ObjCInterfaceDecl *Class
3978 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3979 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3980 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3981 Method->isInstanceMethod()))
3982 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003983 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003984
3985 return clang_getNullCursor();
3986 }
3987
3988 case Decl::ObjCCategory:
3989 if (ObjCCategoryImplDecl *Impl
3990 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003991 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003992 return clang_getNullCursor();
3993
3994 case Decl::ObjCProtocol:
3995 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3996 return C;
3997 return clang_getNullCursor();
3998
3999 case Decl::ObjCInterface:
4000 // There are two notions of a "definition" for an Objective-C
4001 // class: the interface and its implementation. When we resolved a
4002 // reference to an Objective-C class, produce the @interface as
4003 // the definition; when we were provided with the interface,
4004 // produce the @implementation as the definition.
4005 if (WasReference) {
4006 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4007 return C;
4008 } else if (ObjCImplementationDecl *Impl
4009 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004010 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004011 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004012
Douglas Gregorb6998662010-01-19 19:34:47 +00004013 case Decl::ObjCProperty:
4014 // FIXME: We don't really know where to find the
4015 // ObjCPropertyImplDecls that implement this property.
4016 return clang_getNullCursor();
4017
4018 case Decl::ObjCCompatibleAlias:
4019 if (ObjCInterfaceDecl *Class
4020 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4021 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004022 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004023
Douglas Gregorb6998662010-01-19 19:34:47 +00004024 return clang_getNullCursor();
4025
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004026 case Decl::ObjCForwardProtocol:
4027 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004028 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004029
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004030 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004031 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004032 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00004033
4034 case Decl::Friend:
4035 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004036 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004037 return clang_getNullCursor();
4038
4039 case Decl::FriendTemplate:
4040 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004041 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00004042 return clang_getNullCursor();
4043 }
4044
4045 return clang_getNullCursor();
4046}
4047
4048unsigned clang_isCursorDefinition(CXCursor C) {
4049 if (!clang_isDeclaration(C.kind))
4050 return 0;
4051
4052 return clang_getCursorDefinition(C) == C;
4053}
4054
Douglas Gregor1a9d0502010-11-19 23:44:15 +00004055CXCursor clang_getCanonicalCursor(CXCursor C) {
4056 if (!clang_isDeclaration(C.kind))
4057 return C;
4058
4059 if (Decl *D = getCursorDecl(C))
4060 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4061
4062 return C;
4063}
4064
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004065unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004066 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004067 return 0;
4068
4069 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4070 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4071 return E->getNumDecls();
4072
4073 if (OverloadedTemplateStorage *S
4074 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4075 return S->size();
4076
4077 Decl *D = Storage.get<Decl*>();
4078 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00004079 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004080 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4081 return Classes->size();
4082 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4083 return Protocols->protocol_size();
4084
4085 return 0;
4086}
4087
4088CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004089 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004090 return clang_getNullCursor();
4091
4092 if (index >= clang_getNumOverloadedDecls(cursor))
4093 return clang_getNullCursor();
4094
Ted Kremeneka60ed472010-11-16 08:15:36 +00004095 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004096 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4097 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004098 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004099
4100 if (OverloadedTemplateStorage *S
4101 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004102 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004103
4104 Decl *D = Storage.get<Decl*>();
4105 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4106 // FIXME: This is, unfortunately, linear time.
4107 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4108 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004109 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004110 }
4111
4112 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004113 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004114
4115 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004116 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004117
4118 return clang_getNullCursor();
4119}
4120
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004121void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004122 const char **startBuf,
4123 const char **endBuf,
4124 unsigned *startLine,
4125 unsigned *startColumn,
4126 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004127 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004128 assert(getCursorDecl(C) && "CXCursor has null decl");
4129 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004130 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4131 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004132
Steve Naroff4ade6d62009-09-23 17:52:52 +00004133 SourceManager &SM = FD->getASTContext().getSourceManager();
4134 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4135 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4136 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4137 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4138 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4139 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4140}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004141
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004142void clang_enableStackTraces(void) {
4143 llvm::sys::PrintStackTraceOnErrorSignal();
4144}
4145
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004146void clang_executeOnThread(void (*fn)(void*), void *user_data,
4147 unsigned stack_size) {
4148 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4149}
4150
Ted Kremenekfb480492010-01-13 21:46:36 +00004151} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004152
Ted Kremenekfb480492010-01-13 21:46:36 +00004153//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004154// Token-based Operations.
4155//===----------------------------------------------------------------------===//
4156
4157/* CXToken layout:
4158 * int_data[0]: a CXTokenKind
4159 * int_data[1]: starting token location
4160 * int_data[2]: token length
4161 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004162 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004163 * otherwise unused.
4164 */
4165extern "C" {
4166
4167CXTokenKind clang_getTokenKind(CXToken CXTok) {
4168 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4169}
4170
4171CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4172 switch (clang_getTokenKind(CXTok)) {
4173 case CXToken_Identifier:
4174 case CXToken_Keyword:
4175 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004176 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4177 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004178
4179 case CXToken_Literal: {
4180 // We have stashed the starting pointer in the ptr_data field. Use it.
4181 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004182 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004183 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004184
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004185 case CXToken_Punctuation:
4186 case CXToken_Comment:
4187 break;
4188 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004189
4190 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004191 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004192 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004193 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004194 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004195
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004196 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4197 std::pair<FileID, unsigned> LocInfo
4198 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004199 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004200 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004201 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4202 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004203 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004204
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004205 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004206}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004207
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004208CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004209 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004210 if (!CXXUnit)
4211 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004212
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004213 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4214 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4215}
4216
4217CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004218 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004219 if (!CXXUnit)
4220 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004221
4222 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004223 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4224}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004225
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004226void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4227 CXToken **Tokens, unsigned *NumTokens) {
4228 if (Tokens)
4229 *Tokens = 0;
4230 if (NumTokens)
4231 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004232
Ted Kremeneka60ed472010-11-16 08:15:36 +00004233 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004234 if (!CXXUnit || !Tokens || !NumTokens)
4235 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004236
Douglas Gregorbdf60622010-03-05 21:16:25 +00004237 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4238
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004239 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004240 if (R.isInvalid())
4241 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004242
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004243 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4244 std::pair<FileID, unsigned> BeginLocInfo
4245 = SourceMgr.getDecomposedLoc(R.getBegin());
4246 std::pair<FileID, unsigned> EndLocInfo
4247 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004248
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004249 // Cannot tokenize across files.
4250 if (BeginLocInfo.first != EndLocInfo.first)
4251 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004252
4253 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004254 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004255 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004256 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004257 if (Invalid)
4258 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004259
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004260 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4261 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004262 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004263 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004264
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004265 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004266 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004267 llvm::SmallVector<CXToken, 32> CXTokens;
4268 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004269 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004270 do {
4271 // Lex the next token
4272 Lex.LexFromRawLexer(Tok);
4273 if (Tok.is(tok::eof))
4274 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004275
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004276 // Initialize the CXToken.
4277 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004278
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004279 // - Common fields
4280 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4281 CXTok.int_data[2] = Tok.getLength();
4282 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004283
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004284 // - Kind-specific fields
4285 if (Tok.isLiteral()) {
4286 CXTok.int_data[0] = CXToken_Literal;
4287 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004288 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004289 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004290 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004291 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004292
David Chisnall096428b2010-10-13 21:44:48 +00004293 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004294 CXTok.int_data[0] = CXToken_Keyword;
4295 }
4296 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004297 CXTok.int_data[0] = Tok.is(tok::identifier)
4298 ? CXToken_Identifier
4299 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004300 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004301 CXTok.ptr_data = II;
4302 } else if (Tok.is(tok::comment)) {
4303 CXTok.int_data[0] = CXToken_Comment;
4304 CXTok.ptr_data = 0;
4305 } else {
4306 CXTok.int_data[0] = CXToken_Punctuation;
4307 CXTok.ptr_data = 0;
4308 }
4309 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004310 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004311 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004312
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004313 if (CXTokens.empty())
4314 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004315
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004316 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4317 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4318 *NumTokens = CXTokens.size();
4319}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004320
Ted Kremenek6db61092010-05-05 00:55:15 +00004321void clang_disposeTokens(CXTranslationUnit TU,
4322 CXToken *Tokens, unsigned NumTokens) {
4323 free(Tokens);
4324}
4325
4326} // end: extern "C"
4327
4328//===----------------------------------------------------------------------===//
4329// Token annotation APIs.
4330//===----------------------------------------------------------------------===//
4331
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004332typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004333static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4334 CXCursor parent,
4335 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004336namespace {
4337class AnnotateTokensWorker {
4338 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004339 CXToken *Tokens;
4340 CXCursor *Cursors;
4341 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004342 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004343 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004344 CursorVisitor AnnotateVis;
4345 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004346 bool HasContextSensitiveKeywords;
4347
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004348 bool MoreTokens() const { return TokIdx < NumTokens; }
4349 unsigned NextToken() const { return TokIdx; }
4350 void AdvanceToken() { ++TokIdx; }
4351 SourceLocation GetTokenLoc(unsigned tokI) {
4352 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4353 }
4354
Ted Kremenek6db61092010-05-05 00:55:15 +00004355public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004356 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004357 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004358 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004359 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004360 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004361 AnnotateVis(tu,
4362 AnnotateTokensVisitor, this,
Douglas Gregor04a9eb32011-03-16 23:23:30 +00004363 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004364 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4365 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004366
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004367 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004368 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004369 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004370 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004371 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004372 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004373
4374 /// \brief Determine whether the annotator saw any cursors that have
4375 /// context-sensitive keywords.
4376 bool hasContextSensitiveKeywords() const {
4377 return HasContextSensitiveKeywords;
4378 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004379};
4380}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004381
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004382void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4383 // Walk the AST within the region of interest, annotating tokens
4384 // along the way.
4385 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004386
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004387 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4388 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004389 if (Pos != Annotated.end() &&
4390 (clang_isInvalid(Cursors[I].kind) ||
4391 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004392 Cursors[I] = Pos->second;
4393 }
4394
4395 // Finish up annotating any tokens left.
4396 if (!MoreTokens())
4397 return;
4398
4399 const CXCursor &C = clang_getNullCursor();
4400 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4401 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4402 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004403 }
4404}
4405
Ted Kremenek6db61092010-05-05 00:55:15 +00004406enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004407AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004408 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004409 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004410 if (cursorRange.isInvalid())
4411 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004412
4413 if (!HasContextSensitiveKeywords) {
4414 // Objective-C properties can have context-sensitive keywords.
4415 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4416 if (ObjCPropertyDecl *Property
4417 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4418 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4419 }
4420 // Objective-C methods can have context-sensitive keywords.
4421 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4422 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4423 if (ObjCMethodDecl *Method
4424 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4425 if (Method->getObjCDeclQualifier())
4426 HasContextSensitiveKeywords = true;
4427 else {
4428 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4429 PEnd = Method->param_end();
4430 P != PEnd; ++P) {
4431 if ((*P)->getObjCDeclQualifier()) {
4432 HasContextSensitiveKeywords = true;
4433 break;
4434 }
4435 }
4436 }
4437 }
4438 }
4439 // C++ methods can have context-sensitive keywords.
4440 else if (cursor.kind == CXCursor_CXXMethod) {
4441 if (CXXMethodDecl *Method
4442 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4443 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4444 HasContextSensitiveKeywords = true;
4445 }
4446 }
4447 // C++ classes can have context-sensitive keywords.
4448 else if (cursor.kind == CXCursor_StructDecl ||
4449 cursor.kind == CXCursor_ClassDecl ||
4450 cursor.kind == CXCursor_ClassTemplate ||
4451 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4452 if (Decl *D = getCursorDecl(cursor))
4453 if (D->hasAttr<FinalAttr>())
4454 HasContextSensitiveKeywords = true;
4455 }
4456 }
4457
Douglas Gregor4419b672010-10-21 06:10:04 +00004458 if (clang_isPreprocessing(cursor.kind)) {
4459 // For macro instantiations, just note where the beginning of the macro
4460 // instantiation occurs.
4461 if (cursor.kind == CXCursor_MacroInstantiation) {
4462 Annotated[Loc.int_data] = cursor;
4463 return CXChildVisit_Recurse;
4464 }
4465
Douglas Gregor4419b672010-10-21 06:10:04 +00004466 // Items in the preprocessing record are kept separate from items in
4467 // declarations, so we keep a separate token index.
4468 unsigned SavedTokIdx = TokIdx;
4469 TokIdx = PreprocessingTokIdx;
4470
4471 // Skip tokens up until we catch up to the beginning of the preprocessing
4472 // entry.
4473 while (MoreTokens()) {
4474 const unsigned I = NextToken();
4475 SourceLocation TokLoc = GetTokenLoc(I);
4476 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4477 case RangeBefore:
4478 AdvanceToken();
4479 continue;
4480 case RangeAfter:
4481 case RangeOverlap:
4482 break;
4483 }
4484 break;
4485 }
4486
4487 // Look at all of the tokens within this range.
4488 while (MoreTokens()) {
4489 const unsigned I = NextToken();
4490 SourceLocation TokLoc = GetTokenLoc(I);
4491 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4492 case RangeBefore:
4493 assert(0 && "Infeasible");
4494 case RangeAfter:
4495 break;
4496 case RangeOverlap:
4497 Cursors[I] = cursor;
4498 AdvanceToken();
4499 continue;
4500 }
4501 break;
4502 }
4503
4504 // Save the preprocessing token index; restore the non-preprocessing
4505 // token index.
4506 PreprocessingTokIdx = TokIdx;
4507 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004508 return CXChildVisit_Recurse;
4509 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004510
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004511 if (cursorRange.isInvalid())
4512 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004513
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004514 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4515
Ted Kremeneka333c662010-05-12 05:29:33 +00004516 // Adjust the annotated range based specific declarations.
4517 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4518 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004519 Decl *D = cxcursor::getCursorDecl(cursor);
4520 // Don't visit synthesized ObjC methods, since they have no syntatic
4521 // representation in the source.
4522 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4523 if (MD->isSynthesized())
4524 return CXChildVisit_Continue;
4525 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004526
4527 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004528 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004529 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4530 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4531 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4532 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4533 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004534 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004535
4536 if (StartLoc.isValid() && L.isValid() &&
4537 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4538 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004539 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004540
Ted Kremenek3f404602010-08-14 01:14:06 +00004541 // If the location of the cursor occurs within a macro instantiation, record
4542 // the spelling location of the cursor in our annotation map. We can then
4543 // paper over the token labelings during a post-processing step to try and
4544 // get cursor mappings for tokens that are the *arguments* of a macro
4545 // instantiation.
4546 if (L.isMacroID()) {
4547 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4548 // Only invalidate the old annotation if it isn't part of a preprocessing
4549 // directive. Here we assume that the default construction of CXCursor
4550 // results in CXCursor.kind being an initialized value (i.e., 0). If
4551 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004552
Ted Kremenek3f404602010-08-14 01:14:06 +00004553 CXCursor &oldC = Annotated[rawEncoding];
4554 if (!clang_isPreprocessing(oldC.kind))
4555 oldC = cursor;
4556 }
4557
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004558 const enum CXCursorKind K = clang_getCursorKind(parent);
4559 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004560 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4561 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004562
4563 while (MoreTokens()) {
4564 const unsigned I = NextToken();
4565 SourceLocation TokLoc = GetTokenLoc(I);
4566 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4567 case RangeBefore:
4568 Cursors[I] = updateC;
4569 AdvanceToken();
4570 continue;
4571 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004572 case RangeOverlap:
4573 break;
4574 }
4575 break;
4576 }
4577
4578 // Visit children to get their cursor information.
4579 const unsigned BeforeChildren = NextToken();
4580 VisitChildren(cursor);
4581 const unsigned AfterChildren = NextToken();
4582
4583 // Adjust 'Last' to the last token within the extent of the cursor.
4584 while (MoreTokens()) {
4585 const unsigned I = NextToken();
4586 SourceLocation TokLoc = GetTokenLoc(I);
4587 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4588 case RangeBefore:
4589 assert(0 && "Infeasible");
4590 case RangeAfter:
4591 break;
4592 case RangeOverlap:
4593 Cursors[I] = updateC;
4594 AdvanceToken();
4595 continue;
4596 }
4597 break;
4598 }
4599 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004600
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004601 // Scan the tokens that are at the beginning of the cursor, but are not
4602 // capture by the child cursors.
4603
4604 // For AST elements within macros, rely on a post-annotate pass to
4605 // to correctly annotate the tokens with cursors. Otherwise we can
4606 // get confusing results of having tokens that map to cursors that really
4607 // are expanded by an instantiation.
4608 if (L.isMacroID())
4609 cursor = clang_getNullCursor();
4610
4611 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4612 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4613 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004614
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004615 Cursors[I] = cursor;
4616 }
4617 // Scan the tokens that are at the end of the cursor, but are not captured
4618 // but the child cursors.
4619 for (unsigned I = AfterChildren; I != Last; ++I)
4620 Cursors[I] = cursor;
4621
4622 TokIdx = Last;
4623 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004624}
4625
Ted Kremenek6db61092010-05-05 00:55:15 +00004626static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4627 CXCursor parent,
4628 CXClientData client_data) {
4629 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4630}
4631
Ted Kremenek6628a612011-03-18 22:51:30 +00004632namespace {
4633 struct clang_annotateTokens_Data {
4634 CXTranslationUnit TU;
4635 ASTUnit *CXXUnit;
4636 CXToken *Tokens;
4637 unsigned NumTokens;
4638 CXCursor *Cursors;
4639 };
4640}
4641
Ted Kremenekab979612010-11-11 08:05:23 +00004642// This gets run a separate thread to avoid stack blowout.
Ted Kremenek6628a612011-03-18 22:51:30 +00004643static void clang_annotateTokensImpl(void *UserData) {
4644 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4645 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4646 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4647 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4648 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4649
4650 // Determine the region of interest, which contains all of the tokens.
4651 SourceRange RegionOfInterest;
4652 RegionOfInterest.setBegin(
4653 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4654 RegionOfInterest.setEnd(
4655 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4656 Tokens[NumTokens-1])));
4657
4658 // A mapping from the source locations found when re-lexing or traversing the
4659 // region of interest to the corresponding cursors.
4660 AnnotateTokensData Annotated;
4661
4662 // Relex the tokens within the source range to look for preprocessing
4663 // directives.
4664 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4665 std::pair<FileID, unsigned> BeginLocInfo
4666 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4667 std::pair<FileID, unsigned> EndLocInfo
4668 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4669
4670 llvm::StringRef Buffer;
4671 bool Invalid = false;
4672 if (BeginLocInfo.first == EndLocInfo.first &&
4673 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4674 !Invalid) {
4675 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4676 CXXUnit->getASTContext().getLangOptions(),
4677 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4678 Buffer.end());
4679 Lex.SetCommentRetentionState(true);
4680
4681 // Lex tokens in raw mode until we hit the end of the range, to avoid
4682 // entering #includes or expanding macros.
4683 while (true) {
4684 Token Tok;
4685 Lex.LexFromRawLexer(Tok);
4686
4687 reprocess:
4688 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4689 // We have found a preprocessing directive. Gobble it up so that we
4690 // don't see it while preprocessing these tokens later, but keep track
4691 // of all of the token locations inside this preprocessing directive so
4692 // that we can annotate them appropriately.
4693 //
4694 // FIXME: Some simple tests here could identify macro definitions and
4695 // #undefs, to provide specific cursor kinds for those.
4696 llvm::SmallVector<SourceLocation, 32> Locations;
4697 do {
4698 Locations.push_back(Tok.getLocation());
4699 Lex.LexFromRawLexer(Tok);
4700 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4701
4702 using namespace cxcursor;
4703 CXCursor Cursor
4704 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4705 Locations.back()),
4706 TU);
4707 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4708 Annotated[Locations[I].getRawEncoding()] = Cursor;
4709 }
4710
4711 if (Tok.isAtStartOfLine())
4712 goto reprocess;
4713
4714 continue;
4715 }
4716
4717 if (Tok.is(tok::eof))
4718 break;
4719 }
4720 }
4721
4722 // Annotate all of the source locations in the region of interest that map to
4723 // a specific cursor.
4724 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4725 TU, RegionOfInterest);
4726
4727 // FIXME: We use a ridiculous stack size here because the data-recursion
4728 // algorithm uses a large stack frame than the non-data recursive version,
4729 // and AnnotationTokensWorker currently transforms the data-recursion
4730 // algorithm back into a traditional recursion by explicitly calling
4731 // VisitChildren(). We will need to remove this explicit recursive call.
4732 W.AnnotateTokens();
4733
4734 // If we ran into any entities that involve context-sensitive keywords,
4735 // take another pass through the tokens to mark them as such.
4736 if (W.hasContextSensitiveKeywords()) {
4737 for (unsigned I = 0; I != NumTokens; ++I) {
4738 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4739 continue;
4740
4741 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4742 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4743 if (ObjCPropertyDecl *Property
4744 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4745 if (Property->getPropertyAttributesAsWritten() != 0 &&
4746 llvm::StringSwitch<bool>(II->getName())
4747 .Case("readonly", true)
4748 .Case("assign", true)
4749 .Case("readwrite", true)
4750 .Case("retain", true)
4751 .Case("copy", true)
4752 .Case("nonatomic", true)
4753 .Case("atomic", true)
4754 .Case("getter", true)
4755 .Case("setter", true)
4756 .Default(false))
4757 Tokens[I].int_data[0] = CXToken_Keyword;
4758 }
4759 continue;
4760 }
4761
4762 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4763 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4764 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4765 if (llvm::StringSwitch<bool>(II->getName())
4766 .Case("in", true)
4767 .Case("out", true)
4768 .Case("inout", true)
4769 .Case("oneway", true)
4770 .Case("bycopy", true)
4771 .Case("byref", true)
4772 .Default(false))
4773 Tokens[I].int_data[0] = CXToken_Keyword;
4774 continue;
4775 }
4776
4777 if (Cursors[I].kind == CXCursor_CXXMethod) {
4778 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4779 if (CXXMethodDecl *Method
4780 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4781 if ((Method->hasAttr<FinalAttr>() ||
4782 Method->hasAttr<OverrideAttr>()) &&
4783 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4784 llvm::StringSwitch<bool>(II->getName())
4785 .Case("final", true)
4786 .Case("override", true)
4787 .Default(false))
4788 Tokens[I].int_data[0] = CXToken_Keyword;
4789 }
4790 continue;
4791 }
4792
4793 if (Cursors[I].kind == CXCursor_ClassDecl ||
4794 Cursors[I].kind == CXCursor_StructDecl ||
4795 Cursors[I].kind == CXCursor_ClassTemplate) {
4796 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4797 if (II->getName() == "final") {
4798 // We have to be careful with 'final', since it could be the name
4799 // of a member class rather than the context-sensitive keyword.
4800 // So, check whether the cursor associated with this
4801 Decl *D = getCursorDecl(Cursors[I]);
4802 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4803 if ((Record->hasAttr<FinalAttr>()) &&
4804 Record->getIdentifier() != II)
4805 Tokens[I].int_data[0] = CXToken_Keyword;
4806 } else if (ClassTemplateDecl *ClassTemplate
4807 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4808 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4809 if ((Record->hasAttr<FinalAttr>()) &&
4810 Record->getIdentifier() != II)
4811 Tokens[I].int_data[0] = CXToken_Keyword;
4812 }
4813 }
4814 continue;
4815 }
4816 }
4817 }
Ted Kremenekab979612010-11-11 08:05:23 +00004818}
4819
Ted Kremenek6db61092010-05-05 00:55:15 +00004820extern "C" {
4821
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004822void clang_annotateTokens(CXTranslationUnit TU,
4823 CXToken *Tokens, unsigned NumTokens,
4824 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004825
4826 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004827 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004828
Douglas Gregor4419b672010-10-21 06:10:04 +00004829 // Any token we don't specifically annotate will have a NULL cursor.
4830 CXCursor C = clang_getNullCursor();
4831 for (unsigned I = 0; I != NumTokens; ++I)
4832 Cursors[I] = C;
4833
Ted Kremeneka60ed472010-11-16 08:15:36 +00004834 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004835 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004836 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004837
Douglas Gregorbdf60622010-03-05 21:16:25 +00004838 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek6628a612011-03-18 22:51:30 +00004839
4840 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekab979612010-11-11 08:05:23 +00004841 llvm::CrashRecoveryContext CRC;
Ted Kremenek6628a612011-03-18 22:51:30 +00004842 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004843 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004844 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4845 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004846}
Ted Kremenek6628a612011-03-18 22:51:30 +00004847
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004848} // end: extern "C"
4849
4850//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004851// Operations for querying linkage of a cursor.
4852//===----------------------------------------------------------------------===//
4853
4854extern "C" {
4855CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004856 if (!clang_isDeclaration(cursor.kind))
4857 return CXLinkage_Invalid;
4858
Ted Kremenek16b42592010-03-03 06:36:57 +00004859 Decl *D = cxcursor::getCursorDecl(cursor);
4860 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4861 switch (ND->getLinkage()) {
4862 case NoLinkage: return CXLinkage_NoLinkage;
4863 case InternalLinkage: return CXLinkage_Internal;
4864 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4865 case ExternalLinkage: return CXLinkage_External;
4866 };
4867
4868 return CXLinkage_Invalid;
4869}
4870} // end: extern "C"
4871
4872//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004873// Operations for querying language of a cursor.
4874//===----------------------------------------------------------------------===//
4875
4876static CXLanguageKind getDeclLanguage(const Decl *D) {
4877 switch (D->getKind()) {
4878 default:
4879 break;
4880 case Decl::ImplicitParam:
4881 case Decl::ObjCAtDefsField:
4882 case Decl::ObjCCategory:
4883 case Decl::ObjCCategoryImpl:
4884 case Decl::ObjCClass:
4885 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004886 case Decl::ObjCForwardProtocol:
4887 case Decl::ObjCImplementation:
4888 case Decl::ObjCInterface:
4889 case Decl::ObjCIvar:
4890 case Decl::ObjCMethod:
4891 case Decl::ObjCProperty:
4892 case Decl::ObjCPropertyImpl:
4893 case Decl::ObjCProtocol:
4894 return CXLanguage_ObjC;
4895 case Decl::CXXConstructor:
4896 case Decl::CXXConversion:
4897 case Decl::CXXDestructor:
4898 case Decl::CXXMethod:
4899 case Decl::CXXRecord:
4900 case Decl::ClassTemplate:
4901 case Decl::ClassTemplatePartialSpecialization:
4902 case Decl::ClassTemplateSpecialization:
4903 case Decl::Friend:
4904 case Decl::FriendTemplate:
4905 case Decl::FunctionTemplate:
4906 case Decl::LinkageSpec:
4907 case Decl::Namespace:
4908 case Decl::NamespaceAlias:
4909 case Decl::NonTypeTemplateParm:
4910 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004911 case Decl::TemplateTemplateParm:
4912 case Decl::TemplateTypeParm:
4913 case Decl::UnresolvedUsingTypename:
4914 case Decl::UnresolvedUsingValue:
4915 case Decl::Using:
4916 case Decl::UsingDirective:
4917 case Decl::UsingShadow:
4918 return CXLanguage_CPlusPlus;
4919 }
4920
4921 return CXLanguage_C;
4922}
4923
4924extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004925
4926enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4927 if (clang_isDeclaration(cursor.kind))
4928 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004929 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregor58ddb602010-08-23 23:00:57 +00004930 return CXAvailability_Available;
4931
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004932 switch (D->getAvailability()) {
4933 case AR_Available:
4934 case AR_NotYetIntroduced:
4935 return CXAvailability_Available;
4936
4937 case AR_Deprecated:
Douglas Gregor58ddb602010-08-23 23:00:57 +00004938 return CXAvailability_Deprecated;
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004939
4940 case AR_Unavailable:
4941 return CXAvailability_NotAvailable;
4942 }
Douglas Gregor58ddb602010-08-23 23:00:57 +00004943 }
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00004944
Douglas Gregor58ddb602010-08-23 23:00:57 +00004945 return CXAvailability_Available;
4946}
4947
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004948CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4949 if (clang_isDeclaration(cursor.kind))
4950 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4951
4952 return CXLanguage_Invalid;
4953}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004954
4955 /// \brief If the given cursor is the "templated" declaration
4956 /// descibing a class or function template, return the class or
4957 /// function template.
4958static Decl *maybeGetTemplateCursor(Decl *D) {
4959 if (!D)
4960 return 0;
4961
4962 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4963 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4964 return FunTmpl;
4965
4966 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4967 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4968 return ClassTmpl;
4969
4970 return D;
4971}
4972
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004973CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4974 if (clang_isDeclaration(cursor.kind)) {
4975 if (Decl *D = getCursorDecl(cursor)) {
4976 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004977 if (!DC)
4978 return clang_getNullCursor();
4979
4980 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4981 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004982 }
4983 }
4984
4985 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4986 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004987 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004988 }
4989
4990 return clang_getNullCursor();
4991}
4992
4993CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4994 if (clang_isDeclaration(cursor.kind)) {
4995 if (Decl *D = getCursorDecl(cursor)) {
4996 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004997 if (!DC)
4998 return clang_getNullCursor();
4999
5000 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5001 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00005002 }
5003 }
5004
5005 // FIXME: Note that we can't easily compute the lexical context of a
5006 // statement or expression, so we return nothing.
5007 return clang_getNullCursor();
5008}
5009
Douglas Gregor9f592342010-10-01 20:25:15 +00005010static void CollectOverriddenMethods(DeclContext *Ctx,
5011 ObjCMethodDecl *Method,
5012 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5013 if (!Ctx)
5014 return;
5015
5016 // If we have a class or category implementation, jump straight to the
5017 // interface.
5018 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5019 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5020
5021 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5022 if (!Container)
5023 return;
5024
5025 // Check whether we have a matching method at this level.
5026 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5027 Method->isInstanceMethod()))
5028 if (Method != Overridden) {
5029 // We found an override at this level; there is no need to look
5030 // into other protocols or categories.
5031 Methods.push_back(Overridden);
5032 return;
5033 }
5034
5035 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5036 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5037 PEnd = Protocol->protocol_end();
5038 P != PEnd; ++P)
5039 CollectOverriddenMethods(*P, Method, Methods);
5040 }
5041
5042 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5043 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5044 PEnd = Category->protocol_end();
5045 P != PEnd; ++P)
5046 CollectOverriddenMethods(*P, Method, Methods);
5047 }
5048
5049 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5050 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5051 PEnd = Interface->protocol_end();
5052 P != PEnd; ++P)
5053 CollectOverriddenMethods(*P, Method, Methods);
5054
5055 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5056 Category; Category = Category->getNextClassCategory())
5057 CollectOverriddenMethods(Category, Method, Methods);
5058
5059 // We only look into the superclass if we haven't found anything yet.
5060 if (Methods.empty())
5061 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5062 return CollectOverriddenMethods(Super, Method, Methods);
5063 }
5064}
5065
5066void clang_getOverriddenCursors(CXCursor cursor,
5067 CXCursor **overridden,
5068 unsigned *num_overridden) {
5069 if (overridden)
5070 *overridden = 0;
5071 if (num_overridden)
5072 *num_overridden = 0;
5073 if (!overridden || !num_overridden)
5074 return;
5075
5076 if (!clang_isDeclaration(cursor.kind))
5077 return;
5078
5079 Decl *D = getCursorDecl(cursor);
5080 if (!D)
5081 return;
5082
5083 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00005084 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00005085 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5086 *num_overridden = CXXMethod->size_overridden_methods();
5087 if (!*num_overridden)
5088 return;
5089
5090 *overridden = new CXCursor [*num_overridden];
5091 unsigned I = 0;
5092 for (CXXMethodDecl::method_iterator
5093 M = CXXMethod->begin_overridden_methods(),
5094 MEnd = CXXMethod->end_overridden_methods();
5095 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005096 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005097 return;
5098 }
5099
5100 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5101 if (!Method)
5102 return;
5103
5104 // Handle Objective-C methods.
5105 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5106 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5107
5108 if (Methods.empty())
5109 return;
5110
5111 *num_overridden = Methods.size();
5112 *overridden = new CXCursor [Methods.size()];
5113 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005114 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005115}
5116
5117void clang_disposeOverriddenCursors(CXCursor *overridden) {
5118 delete [] overridden;
5119}
5120
Douglas Gregorecdcb882010-10-20 22:00:55 +00005121CXFile clang_getIncludedFile(CXCursor cursor) {
5122 if (cursor.kind != CXCursor_InclusionDirective)
5123 return 0;
5124
5125 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5126 return (void *)ID->getFile();
5127}
5128
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005129} // end: extern "C"
5130
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005131
5132//===----------------------------------------------------------------------===//
5133// C++ AST instrospection.
5134//===----------------------------------------------------------------------===//
5135
5136extern "C" {
5137unsigned clang_CXXMethod_isStatic(CXCursor C) {
5138 if (!clang_isDeclaration(C.kind))
5139 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005140
5141 CXXMethodDecl *Method = 0;
5142 Decl *D = cxcursor::getCursorDecl(C);
5143 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5144 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5145 else
5146 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5147 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005148}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005149
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005150} // end: extern "C"
5151
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005152//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005153// Attribute introspection.
5154//===----------------------------------------------------------------------===//
5155
5156extern "C" {
5157CXType clang_getIBOutletCollectionType(CXCursor C) {
5158 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005159 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005160
5161 IBOutletCollectionAttr *A =
5162 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5163
Douglas Gregor841b2382011-03-06 18:55:32 +00005164 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005165}
5166} // end: extern "C"
5167
5168//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005169// Misc. utility functions.
5170//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005171
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005172/// Default to using an 8 MB stack size on "safety" threads.
5173static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005174
5175namespace clang {
5176
5177bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005178 void (*Fn)(void*), void *UserData,
5179 unsigned Size) {
5180 if (!Size)
5181 Size = GetSafetyThreadStackSize();
5182 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005183 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5184 return CRC.RunSafely(Fn, UserData);
5185}
5186
5187unsigned GetSafetyThreadStackSize() {
5188 return SafetyStackThreadSize;
5189}
5190
5191void SetSafetyThreadStackSize(unsigned Value) {
5192 SafetyStackThreadSize = Value;
5193}
5194
5195}
5196
Ted Kremenek04bb7162010-01-22 22:44:15 +00005197extern "C" {
5198
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005199CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005200 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005201}
5202
5203} // end: extern "C"