blob: 16672ca70401f8036d9a7c8478c863d5a2de1dde [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
191 /// \brief When valid, a source range to which the cursor should restrict
192 /// its search.
193 SourceRange RegionOfInterest;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000194
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000195 // FIXME: Eventually remove. This part of a hack to support proper
196 // iteration over all Decls contained lexically within an ObjC container.
197 DeclContext::decl_iterator *DI_current;
198 DeclContext::decl_iterator DE_current;
199
Ted Kremenekd1ded662010-11-15 23:31:32 +0000200 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
201 llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
202 llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
203
Douglas Gregorb1373d02010-01-20 20:59:29 +0000204 using DeclVisitor<CursorVisitor, bool>::Visit;
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000205 using TypeLocVisitor<CursorVisitor, bool>::Visit;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000206
207 /// \brief Determine whether this particular source range comes before, comes
208 /// after, or overlaps the region of interest.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000209 ///
Daniel Dunbard52864b2010-02-14 10:02:57 +0000210 /// \param R a half-open source range retrieved from the abstract syntax tree.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000211 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
212
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000213 class SetParentRAII {
214 CXCursor &Parent;
215 Decl *&StmtParent;
216 CXCursor OldParent;
217
218 public:
219 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
220 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
221 {
222 Parent = NewParent;
223 if (clang_isDeclaration(Parent.kind))
224 StmtParent = getCursorDecl(Parent);
225 }
226
227 ~SetParentRAII() {
228 Parent = OldParent;
229 if (clang_isDeclaration(Parent.kind))
230 StmtParent = getCursorDecl(Parent);
231 }
232 };
233
Steve Naroff89922f82009-08-31 00:59:03 +0000234public:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000235 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
236 CXClientData ClientData,
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000237 unsigned MaxPCHLevel,
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000238 SourceRange RegionOfInterest = SourceRange())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000239 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
240 Visitor(Visitor), ClientData(ClientData),
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000241 MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest),
242 DI_current(0)
Douglas Gregorb1373d02010-01-20 20:59:29 +0000243 {
244 Parent.kind = CXCursor_NoDeclFound;
245 Parent.data[0] = 0;
246 Parent.data[1] = 0;
247 Parent.data[2] = 0;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000248 StmtParent = 0;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000249 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000250
Ted Kremenekd1ded662010-11-15 23:31:32 +0000251 ~CursorVisitor() {
252 // Free the pre-allocated worklists for data-recursion.
253 for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
254 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
255 delete *I;
256 }
257 }
258
Ted Kremeneka60ed472010-11-16 08:15:36 +0000259 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
260 CXTranslationUnit getTU() const { return TU; }
Ted Kremenekab979612010-11-11 08:05:23 +0000261
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000262 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000263
264 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
265 getPreprocessedEntities();
266
Douglas Gregorb1373d02010-01-20 20:59:29 +0000267 bool VisitChildren(CXCursor Parent);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000268
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000269 // Declaration visitors
Ted Kremenek09dfa372010-02-18 05:46:33 +0000270 bool VisitAttributes(Decl *D);
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000271 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenek3064ef92010-08-27 21:34:58 +0000272 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000273 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000274 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000275 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
276 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000277 bool VisitTagDecl(TagDecl *D);
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000278 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregor74dbe642010-08-31 19:31:58 +0000279 bool VisitClassTemplatePartialSpecializationDecl(
280 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000281 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000282 bool VisitEnumConstantDecl(EnumConstantDecl *D);
283 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
284 bool VisitFunctionDecl(FunctionDecl *ND);
285 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek4540c9c2010-02-18 18:47:08 +0000286 bool VisitVarDecl(VarDecl *);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000287 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000288 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor39d6f072010-08-31 19:02:00 +0000289 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor84b51d72010-09-01 20:16:53 +0000290 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000291 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
292 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
293 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
294 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek23173d72010-05-18 21:09:07 +0000295 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremenek79758f62010-02-18 22:36:18 +0000296 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
297 bool VisitObjCImplDecl(ObjCImplDecl *D);
298 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
299 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremenek79758f62010-02-18 22:36:18 +0000300 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
301 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
302 bool VisitObjCClassDecl(ObjCClassDecl *D);
Douglas Gregora4ffd852010-11-17 01:03:52 +0000303 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
Ted Kremeneka0536d82010-05-07 01:04:29 +0000304 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenek8f06e0e2010-05-06 23:38:21 +0000305 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregor69319002010-08-31 23:48:11 +0000306 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000307 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregor7e242562010-09-01 19:52:22 +0000308 bool VisitUsingDecl(UsingDecl *D);
309 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
310 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor0a35bce2010-09-01 03:07:18 +0000311
Douglas Gregor01829d32010-08-31 14:41:23 +0000312 // Name visitor
313 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000314 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregordc355712011-02-25 00:36:19 +0000315 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
Douglas Gregor01829d32010-08-31 14:41:23 +0000316
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000317 // Template visitors
318 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregor0b36e612010-08-31 20:37:03 +0000319 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000320 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
321
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000322 // Type visitors
Douglas Gregor01829d32010-08-31 14:41:23 +0000323 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000324 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000325 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000326 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
327 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000328 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000329 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCallc12c5bb2010-05-15 11:32:37 +0000330 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000331 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
Abramo Bagnara075f8f12010-12-10 16:29:40 +0000332 bool VisitParenTypeLoc(ParenTypeLoc TL);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000333 bool VisitPointerTypeLoc(PointerTypeLoc TL);
334 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
335 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
336 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
337 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor01829d32010-08-31 14:41:23 +0000338 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregorf20dfbc2010-01-21 17:29:07 +0000339 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000340 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000341 // FIXME: Implement visitors here when the unimplemented TypeLocs get
342 // implemented
343 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
Douglas Gregor7536dd52010-12-20 02:24:11 +0000344 bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
Douglas Gregor2332c112010-01-21 20:48:56 +0000345 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000346 bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
Douglas Gregor94fdffa2011-03-01 20:11:18 +0000347 bool VisitDependentTemplateSpecializationTypeLoc(
348 DependentTemplateSpecializationTypeLoc TL);
Douglas Gregor9e876872011-03-01 18:12:44 +0000349 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
Douglas Gregor2494dd02011-03-01 01:34:45 +0000350
Ted Kremenekc0e1d922010-11-11 08:05:18 +0000351 // Data-recursive visitor functions.
352 bool IsInRegionOfInterest(CXCursor C);
353 bool RunVisitorWorkList(VisitorWorkList &WL);
354 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
Ted Kremenekcdba6592010-11-18 00:42:18 +0000355 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
Steve Naroff89922f82009-08-31 00:59:03 +0000356};
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000357
Ted Kremenekab188932010-01-05 19:32:54 +0000358} // end anonymous namespace
Benjamin Kramer5e4bc592009-10-18 16:11:04 +0000359
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000360static SourceRange getRawCursorExtent(CXCursor C);
Douglas Gregor66537982010-11-17 17:14:07 +0000361static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
362
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000363
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000364RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000365 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000366}
367
Douglas Gregorb1373d02010-01-20 20:59:29 +0000368/// \brief Visit the given cursor and, if requested by the visitor,
369/// its children.
370///
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000371/// \param Cursor the cursor to visit.
372///
373/// \param CheckRegionOfInterest if true, then the caller already checked that
374/// this cursor is within the region of interest.
375///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000376/// \returns true if the visitation should be aborted, false if it
377/// should continue.
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000378bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregorb1373d02010-01-20 20:59:29 +0000379 if (clang_isInvalid(Cursor.kind))
380 return false;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000381
Douglas Gregorb1373d02010-01-20 20:59:29 +0000382 if (clang_isDeclaration(Cursor.kind)) {
383 Decl *D = getCursorDecl(Cursor);
384 assert(D && "Invalid declaration cursor");
385 if (D->getPCHLevel() > MaxPCHLevel)
386 return false;
387
388 if (D->isImplicit())
389 return false;
390 }
391
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000392 // If we have a range of interest, and this cursor doesn't intersect with it,
393 // we're done.
394 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +0000395 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbarf408f322010-02-14 08:32:05 +0000396 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000397 return false;
398 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000399
Douglas Gregorb1373d02010-01-20 20:59:29 +0000400 switch (Visitor(Cursor, Parent, ClientData)) {
401 case CXChildVisit_Break:
402 return true;
403
404 case CXChildVisit_Continue:
405 return false;
406
407 case CXChildVisit_Recurse:
408 return VisitChildren(Cursor);
409 }
410
Douglas Gregorfd643772010-01-25 16:45:46 +0000411 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000412}
413
Douglas Gregor788f5a12010-03-20 00:41:21 +0000414std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
415CursorVisitor::getPreprocessedEntities() {
416 PreprocessingRecord &PPRec
Ted Kremeneka60ed472010-11-16 08:15:36 +0000417 = *AU->getPreprocessor().getPreprocessingRecord();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000418
419 bool OnlyLocalDecls
Douglas Gregor32038bb2010-12-21 19:07:48 +0000420 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
421
422 if (OnlyLocalDecls && RegionOfInterest.isValid()) {
423 // If we would only look at local declarations but we have a region of
424 // interest, check whether that region of interest is in the main file.
425 // If not, we should traverse all declarations.
426 // FIXME: My kingdom for a proper binary search approach to finding
427 // cursors!
428 std::pair<FileID, unsigned> Location
429 = AU->getSourceManager().getDecomposedInstantiationLoc(
430 RegionOfInterest.getBegin());
431 if (Location.first != AU->getSourceManager().getMainFileID())
432 OnlyLocalDecls = false;
433 }
Douglas Gregor788f5a12010-03-20 00:41:21 +0000434
Douglas Gregor89d99802010-11-30 06:16:57 +0000435 PreprocessingRecord::iterator StartEntity, EndEntity;
436 if (OnlyLocalDecls) {
437 StartEntity = AU->pp_entity_begin();
438 EndEntity = AU->pp_entity_end();
439 } else {
440 StartEntity = PPRec.begin();
441 EndEntity = PPRec.end();
442 }
443
Douglas Gregor788f5a12010-03-20 00:41:21 +0000444 // There is no region of interest; we have to walk everything.
445 if (RegionOfInterest.isInvalid())
Douglas Gregor89d99802010-11-30 06:16:57 +0000446 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000447
448 // Find the file in which the region of interest lands.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000449 SourceManager &SM = AU->getSourceManager();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000450 std::pair<FileID, unsigned> Begin
451 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
452 std::pair<FileID, unsigned> End
453 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
454
455 // The region of interest spans files; we have to walk everything.
456 if (Begin.first != End.first)
Douglas Gregor89d99802010-11-30 06:16:57 +0000457 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor788f5a12010-03-20 00:41:21 +0000458
459 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
Ted Kremeneka60ed472010-11-16 08:15:36 +0000460 = AU->getPreprocessedEntitiesByFile();
Douglas Gregor788f5a12010-03-20 00:41:21 +0000461 if (ByFileMap.empty()) {
462 // Build the mapping from files to sets of preprocessed entities.
Douglas Gregor89d99802010-11-30 06:16:57 +0000463 for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
Douglas Gregor788f5a12010-03-20 00:41:21 +0000464 std::pair<FileID, unsigned> P
465 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
Douglas Gregor89d99802010-11-30 06:16:57 +0000466
Douglas Gregor788f5a12010-03-20 00:41:21 +0000467 ByFileMap[P.first].push_back(*E);
468 }
469 }
470
471 return std::make_pair(ByFileMap[Begin.first].begin(),
472 ByFileMap[Begin.first].end());
473}
474
Douglas Gregorb1373d02010-01-20 20:59:29 +0000475/// \brief Visit the children of the given cursor.
Ted Kremeneka60ed472010-11-16 08:15:36 +0000476///
Douglas Gregorb1373d02010-01-20 20:59:29 +0000477/// \returns true if the visitation should be aborted, false if it
478/// should continue.
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000479bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregorc314aa42011-03-02 19:17:03 +0000480 if (clang_isReference(Cursor.kind) &&
481 Cursor.kind != CXCursor_CXXBaseSpecifier) {
Douglas Gregora59e3902010-01-21 23:27:09 +0000482 // By definition, references have no children.
483 return false;
484 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000485
486 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregorb1373d02010-01-20 20:59:29 +0000487 // done.
Ted Kremenek0f91f6a2010-05-13 00:25:00 +0000488 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000489
Douglas Gregorb1373d02010-01-20 20:59:29 +0000490 if (clang_isDeclaration(Cursor.kind)) {
491 Decl *D = getCursorDecl(Cursor);
492 assert(D && "Invalid declaration cursor");
Ted Kremenek539311e2010-02-18 18:47:01 +0000493 return VisitAttributes(D) || Visit(D);
Douglas Gregorb1373d02010-01-20 20:59:29 +0000494 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000495
Douglas Gregora59e3902010-01-21 23:27:09 +0000496 if (clang_isStatement(Cursor.kind))
497 return Visit(getCursorStmt(Cursor));
498 if (clang_isExpression(Cursor.kind))
499 return Visit(getCursorExpr(Cursor));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000500
Douglas Gregorb1373d02010-01-20 20:59:29 +0000501 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000502 CXTranslationUnit tu = getCursorTU(Cursor);
503 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregor33e9abd2010-01-22 19:49:59 +0000504 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
505 RegionOfInterest.isInvalid()) {
Douglas Gregoreb8837b2010-08-03 19:06:41 +0000506 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
507 TLEnd = CXXUnit->top_level_end();
508 TL != TLEnd; ++TL) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000509 if (Visit(MakeCXCursor(*TL, tu), true))
Douglas Gregor7b691f332010-01-20 21:13:59 +0000510 return true;
511 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000512 } else if (VisitDeclContext(
513 CXXUnit->getASTContext().getTranslationUnitDecl()))
514 return true;
Bob Wilson3178cb62010-03-19 03:57:57 +0000515
Douglas Gregor0396f462010-03-19 05:22:59 +0000516 // Walk the preprocessing record.
Daniel Dunbar8de30ff2010-03-20 01:11:56 +0000517 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
Douglas Gregor0396f462010-03-19 05:22:59 +0000518 // FIXME: Once we have the ability to deserialize a preprocessing record,
519 // do so.
Douglas Gregor788f5a12010-03-20 00:41:21 +0000520 PreprocessingRecord::iterator E, EEnd;
521 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
Douglas Gregor0396f462010-03-19 05:22:59 +0000522 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000523 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
Douglas Gregor0396f462010-03-19 05:22:59 +0000524 return true;
Douglas Gregor788f5a12010-03-20 00:41:21 +0000525
Douglas Gregor0396f462010-03-19 05:22:59 +0000526 continue;
527 }
528
529 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000530 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
Douglas Gregor0396f462010-03-19 05:22:59 +0000531 return true;
532
533 continue;
534 }
Douglas Gregorecdcb882010-10-20 22:00:55 +0000535
536 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000537 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
Douglas Gregorecdcb882010-10-20 22:00:55 +0000538 return true;
539
540 continue;
541 }
Douglas Gregor0396f462010-03-19 05:22:59 +0000542 }
543 }
Douglas Gregor7b691f332010-01-20 21:13:59 +0000544 return false;
Douglas Gregorb1373d02010-01-20 20:59:29 +0000545 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000546
Douglas Gregorc314aa42011-03-02 19:17:03 +0000547 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
548 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
549 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
550 return Visit(BaseTSInfo->getTypeLoc());
551 }
552 }
553 }
554
Douglas Gregorb1373d02010-01-20 20:59:29 +0000555 // Nothing to visit at the moment.
Douglas Gregorb1373d02010-01-20 20:59:29 +0000556 return false;
557}
558
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000559bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
John McCallfc929202010-06-04 22:33:30 +0000560 if (Visit(B->getSignatureAsWritten()->getTypeLoc()))
561 return true;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000562
Ted Kremenek664cffd2010-07-22 11:30:19 +0000563 if (Stmt *Body = B->getBody())
564 return Visit(MakeCXCursor(Body, StmtParent, TU));
565
566 return false;
Ted Kremenek1ee6cad2010-04-11 21:47:37 +0000567}
568
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000569llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
570 if (RegionOfInterest.isValid()) {
Douglas Gregor66537982010-11-17 17:14:07 +0000571 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000572 if (Range.isInvalid())
573 return llvm::Optional<bool>();
Douglas Gregor66537982010-11-17 17:14:07 +0000574
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000575 switch (CompareRegionOfInterest(Range)) {
576 case RangeBefore:
577 // This declaration comes before the region of interest; skip it.
578 return llvm::Optional<bool>();
579
580 case RangeAfter:
581 // This declaration comes after the region of interest; we're done.
582 return false;
583
584 case RangeOverlap:
585 // This declaration overlaps the region of interest; visit it.
586 break;
587 }
588 }
589 return true;
590}
591
592bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
593 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
594
595 // FIXME: Eventually remove. This part of a hack to support proper
596 // iteration over all Decls contained lexically within an ObjC container.
597 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
598 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
599
600 for ( ; I != E; ++I) {
Ted Kremenek23173d72010-05-18 21:09:07 +0000601 Decl *D = *I;
602 if (D->getLexicalDeclContext() != DC)
603 continue;
Ted Kremenek23173d72010-05-18 21:09:07 +0000604 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000605 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
606 if (!V.hasValue())
607 continue;
608 if (!V.getValue())
609 return false;
Daniel Dunbard52864b2010-02-14 10:02:57 +0000610 if (Visit(Cursor, true))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000611 return true;
612 }
Douglas Gregorb1373d02010-01-20 20:59:29 +0000613 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000614}
615
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000616bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
617 llvm_unreachable("Translation units are visited directly by Visit()");
618 return false;
619}
620
621bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
622 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
623 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000624
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000625 return false;
626}
627
628bool CursorVisitor::VisitTagDecl(TagDecl *D) {
629 return VisitDeclContext(D);
630}
631
Douglas Gregor0ab1e9f2010-09-01 17:32:36 +0000632bool CursorVisitor::VisitClassTemplateSpecializationDecl(
633 ClassTemplateSpecializationDecl *D) {
634 bool ShouldVisitBody = false;
635 switch (D->getSpecializationKind()) {
636 case TSK_Undeclared:
637 case TSK_ImplicitInstantiation:
638 // Nothing to visit
639 return false;
640
641 case TSK_ExplicitInstantiationDeclaration:
642 case TSK_ExplicitInstantiationDefinition:
643 break;
644
645 case TSK_ExplicitSpecialization:
646 ShouldVisitBody = true;
647 break;
648 }
649
650 // Visit the template arguments used in the specialization.
651 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
652 TypeLoc TL = SpecType->getTypeLoc();
653 if (TemplateSpecializationTypeLoc *TSTLoc
654 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
655 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
656 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
657 return true;
658 }
659 }
660
661 if (ShouldVisitBody && VisitCXXRecordDecl(D))
662 return true;
663
664 return false;
665}
666
Douglas Gregor74dbe642010-08-31 19:31:58 +0000667bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
668 ClassTemplatePartialSpecializationDecl *D) {
669 // FIXME: Visit the "outer" template parameter lists on the TagDecl
670 // before visiting these template parameters.
671 if (VisitTemplateParameters(D->getTemplateParameters()))
672 return true;
673
674 // Visit the partial specialization arguments.
675 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
676 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
677 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
678 return true;
679
680 return VisitCXXRecordDecl(D);
681}
682
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000683bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor84b51d72010-09-01 20:16:53 +0000684 // Visit the default argument.
685 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
686 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
687 if (Visit(DefArg->getTypeLoc()))
688 return true;
689
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000690 return false;
691}
692
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000693bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
694 if (Expr *Init = D->getInitExpr())
695 return Visit(MakeCXCursor(Init, StmtParent, TU));
696 return false;
697}
698
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000699bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
700 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
701 if (Visit(TSInfo->getTypeLoc()))
702 return true;
703
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000704 // Visit the nested-name-specifier, if present.
705 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
706 if (VisitNestedNameSpecifierLoc(QualifierLoc))
707 return true;
708
Douglas Gregor7d0d40e2010-01-21 16:28:34 +0000709 return false;
710}
711
Douglas Gregora67e03f2010-09-09 21:42:20 +0000712/// \brief Compare two base or member initializers based on their source order.
Sean Huntcbb67482011-01-08 20:30:50 +0000713static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
714 CXXCtorInitializer const * const *X
715 = static_cast<CXXCtorInitializer const * const *>(Xp);
716 CXXCtorInitializer const * const *Y
717 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000718
719 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
720 return -1;
721 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
722 return 1;
723 else
724 return 0;
725}
726
Douglas Gregorb1373d02010-01-20 20:59:29 +0000727bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor01829d32010-08-31 14:41:23 +0000728 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
729 // Visit the function declaration's syntactic components in the order
730 // written. This requires a bit of work.
Abramo Bagnara723df242010-12-14 22:11:44 +0000731 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor01829d32010-08-31 14:41:23 +0000732 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
733
734 // If we have a function declared directly (without the use of a typedef),
735 // visit just the return type. Otherwise, just visit the function's type
736 // now.
737 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
738 (!FTL && Visit(TL)))
739 return true;
740
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000741 // Visit the nested-name-specifier, if present.
Douglas Gregorc22b5ff2011-02-25 02:25:35 +0000742 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
743 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +0000744 return true;
Douglas Gregor01829d32010-08-31 14:41:23 +0000745
746 // Visit the declaration name.
747 if (VisitDeclarationNameInfo(ND->getNameInfo()))
748 return true;
749
750 // FIXME: Visit explicitly-specified template arguments!
751
752 // Visit the function parameters, if we have a function type.
753 if (FTL && VisitFunctionTypeLoc(*FTL, true))
754 return true;
755
756 // FIXME: Attributes?
757 }
758
Douglas Gregora67e03f2010-09-09 21:42:20 +0000759 if (ND->isThisDeclarationADefinition()) {
760 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
761 // Find the initializers that were written in the source.
Sean Huntcbb67482011-01-08 20:30:50 +0000762 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregora67e03f2010-09-09 21:42:20 +0000763 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
764 IEnd = Constructor->init_end();
765 I != IEnd; ++I) {
766 if (!(*I)->isWritten())
767 continue;
768
769 WrittenInits.push_back(*I);
770 }
771
772 // Sort the initializers in source order
773 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Sean Huntcbb67482011-01-08 20:30:50 +0000774 &CompareCXXCtorInitializers);
Douglas Gregora67e03f2010-09-09 21:42:20 +0000775
776 // Visit the initializers in source order
777 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Sean Huntcbb67482011-01-08 20:30:50 +0000778 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichet00eb3f92010-12-04 09:14:42 +0000779 if (Init->isAnyMemberInitializer()) {
780 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregora67e03f2010-09-09 21:42:20 +0000781 Init->getMemberLocation(), TU)))
782 return true;
783 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
784 if (Visit(BaseInfo->getTypeLoc()))
785 return true;
786 }
787
788 // Visit the initializer value.
789 if (Expr *Initializer = Init->getInit())
790 if (Visit(MakeCXCursor(Initializer, ND, TU)))
791 return true;
792 }
793 }
794
795 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
796 return true;
797 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000798
Douglas Gregorb1373d02010-01-20 20:59:29 +0000799 return false;
800}
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000801
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000802bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
803 if (VisitDeclaratorDecl(D))
804 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000805
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000806 if (Expr *BitWidth = D->getBitWidth())
807 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000808
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000809 return false;
810}
811
812bool CursorVisitor::VisitVarDecl(VarDecl *D) {
813 if (VisitDeclaratorDecl(D))
814 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000815
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000816 if (Expr *Init = D->getInit())
817 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000818
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000819 return false;
820}
821
Douglas Gregor84b51d72010-09-01 20:16:53 +0000822bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
823 if (VisitDeclaratorDecl(D))
824 return true;
825
826 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
827 if (Expr *DefArg = D->getDefaultArgument())
828 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
829
830 return false;
831}
832
Douglas Gregorfe72e9c2010-08-31 17:01:39 +0000833bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
834 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
835 // before visiting these template parameters.
836 if (VisitTemplateParameters(D->getTemplateParameters()))
837 return true;
838
839 return VisitFunctionDecl(D->getTemplatedDecl());
840}
841
Douglas Gregor39d6f072010-08-31 19:02:00 +0000842bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
843 // FIXME: Visit the "outer" template parameter lists on the TagDecl
844 // before visiting these template parameters.
845 if (VisitTemplateParameters(D->getTemplateParameters()))
846 return true;
847
848 return VisitCXXRecordDecl(D->getTemplatedDecl());
849}
850
Douglas Gregor84b51d72010-09-01 20:16:53 +0000851bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
852 if (VisitTemplateParameters(D->getTemplateParameters()))
853 return true;
854
855 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
856 VisitTemplateArgumentLoc(D->getDefaultArgument()))
857 return true;
858
859 return false;
860}
861
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000862bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor4bc1cb62010-03-08 14:59:44 +0000863 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
864 if (Visit(TSInfo->getTypeLoc()))
865 return true;
866
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000867 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000868 PEnd = ND->param_end();
869 P != PEnd; ++P) {
870 if (Visit(MakeCXCursor(*P, TU)))
871 return true;
872 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000873
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000874 if (ND->isThisDeclarationADefinition() &&
875 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
876 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000877
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000878 return false;
879}
880
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000881namespace {
882 struct ContainerDeclsSort {
883 SourceManager &SM;
884 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
885 bool operator()(Decl *A, Decl *B) {
886 SourceLocation L_A = A->getLocStart();
887 SourceLocation L_B = B->getLocStart();
888 assert(L_A.isValid() && L_B.isValid());
889 return SM.isBeforeInTranslationUnit(L_A, L_B);
890 }
891 };
892}
893
Douglas Gregora59e3902010-01-21 23:27:09 +0000894bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000895 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
896 // an @implementation can lexically contain Decls that are not properly
897 // nested in the AST. When we identify such cases, we need to retrofit
898 // this nesting here.
899 if (!DI_current)
900 return VisitDeclContext(D);
901
902 // Scan the Decls that immediately come after the container
903 // in the current DeclContext. If any fall within the
904 // container's lexical region, stash them into a vector
905 // for later processing.
906 llvm::SmallVector<Decl *, 24> DeclsInContainer;
907 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000908 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000909 if (EndLoc.isValid()) {
910 DeclContext::decl_iterator next = *DI_current;
911 while (++next != DE_current) {
912 Decl *D_next = *next;
913 if (!D_next)
914 break;
915 SourceLocation L = D_next->getLocStart();
916 if (!L.isValid())
917 break;
918 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
919 *DI_current = next;
920 DeclsInContainer.push_back(D_next);
921 continue;
922 }
923 break;
924 }
925 }
926
927 // The common case.
928 if (DeclsInContainer.empty())
929 return VisitDeclContext(D);
930
931 // Get all the Decls in the DeclContext, and sort them with the
932 // additional ones we've collected. Then visit them.
933 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
934 I!=E; ++I) {
935 Decl *subDecl = *I;
Ted Kremenek0582c892010-11-02 23:17:51 +0000936 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
937 subDecl->getLocStart().isInvalid())
Ted Kremenekd8c370c2010-11-02 23:10:24 +0000938 continue;
939 DeclsInContainer.push_back(subDecl);
940 }
941
942 // Now sort the Decls so that they appear in lexical order.
943 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
944 ContainerDeclsSort(SM));
945
946 // Now visit the decls.
947 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
948 E = DeclsInContainer.end(); I != E; ++I) {
949 CXCursor Cursor = MakeCXCursor(*I, TU);
950 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
951 if (!V.hasValue())
952 continue;
953 if (!V.getValue())
954 return false;
955 if (Visit(Cursor, true))
956 return true;
957 }
958 return false;
Douglas Gregora59e3902010-01-21 23:27:09 +0000959}
960
Douglas Gregorb1373d02010-01-20 20:59:29 +0000961bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000962 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
963 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000964 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000965
Douglas Gregor78db0cd2010-01-16 15:44:18 +0000966 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
967 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
968 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +0000969 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +0000970 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000971
Douglas Gregora59e3902010-01-21 23:27:09 +0000972 return VisitObjCContainerDecl(ND);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +0000973}
974
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000975bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
976 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
977 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
978 E = PID->protocol_end(); I != E; ++I, ++PL)
979 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
980 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +0000981
Douglas Gregor1ef2fc12010-01-22 00:50:27 +0000982 return VisitObjCContainerDecl(PID);
983}
984
Ted Kremenek23173d72010-05-18 21:09:07 +0000985bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor83cb9422010-09-09 17:09:21 +0000986 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCallfc929202010-06-04 22:33:30 +0000987 return true;
988
Ted Kremenek23173d72010-05-18 21:09:07 +0000989 // FIXME: This implements a workaround with @property declarations also being
990 // installed in the DeclContext for the @interface. Eventually this code
991 // should be removed.
992 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
993 if (!CDecl || !CDecl->IsClassExtension())
994 return false;
995
996 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
997 if (!ID)
998 return false;
999
1000 IdentifierInfo *PropertyId = PD->getIdentifier();
1001 ObjCPropertyDecl *prevDecl =
1002 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1003
1004 if (!prevDecl)
1005 return false;
1006
1007 // Visit synthesized methods since they will be skipped when visiting
1008 // the @interface.
1009 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001010 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001011 if (Visit(MakeCXCursor(MD, TU)))
1012 return true;
1013
1014 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremeneka054fb42010-09-21 20:52:59 +00001015 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek23173d72010-05-18 21:09:07 +00001016 if (Visit(MakeCXCursor(MD, TU)))
1017 return true;
1018
1019 return false;
1020}
1021
Douglas Gregorb1373d02010-01-20 20:59:29 +00001022bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001023 // Issue callbacks for super class.
Douglas Gregorb1373d02010-01-20 20:59:29 +00001024 if (D->getSuperClass() &&
1025 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001026 D->getSuperClassLoc(),
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001027 TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001028 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001029
Douglas Gregor78db0cd2010-01-16 15:44:18 +00001030 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1031 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1032 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001033 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001034 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001035
Douglas Gregora59e3902010-01-21 23:27:09 +00001036 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001037}
1038
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001039bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1040 return VisitObjCContainerDecl(D);
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001041}
1042
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001043bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremenekebfa3392010-03-19 20:39:03 +00001044 // 'ID' could be null when dealing with invalid code.
1045 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1046 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1047 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001048
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001049 return VisitObjCImplDecl(D);
1050}
1051
1052bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1053#if 0
1054 // Issue callbacks for super class.
1055 // FIXME: No source location information!
1056 if (D->getSuperClass() &&
1057 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001058 D->getSuperClassLoc(),
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001059 TU)))
1060 return true;
1061#endif
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001062
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001063 return VisitObjCImplDecl(D);
1064}
1065
1066bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1067 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1068 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1069 E = D->protocol_end();
1070 I != E; ++I, ++PL)
Douglas Gregorb2cd4872010-01-20 23:57:43 +00001071 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregorb1373d02010-01-20 20:59:29 +00001072 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001073
1074 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001075}
1076
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001077bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1078 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1079 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1080 return true;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001081
Douglas Gregor1ef2fc12010-01-22 00:50:27 +00001082 return false;
Ted Kremenekdd6bcc52010-01-13 00:22:49 +00001083}
1084
Douglas Gregora4ffd852010-11-17 01:03:52 +00001085bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1086 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1087 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1088
1089 return false;
1090}
1091
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00001092bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1093 return VisitDeclContext(D);
1094}
1095
Douglas Gregor69319002010-08-31 23:48:11 +00001096bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001097 // Visit nested-name-specifier.
Douglas Gregor0cfaf6a2011-02-25 17:08:07 +00001098 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1099 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001100 return true;
Douglas Gregor69319002010-08-31 23:48:11 +00001101
1102 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1103 D->getTargetNameLoc(), TU));
1104}
1105
Douglas Gregor7e242562010-09-01 19:52:22 +00001106bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001107 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001108 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1109 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001110 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001111 }
Douglas Gregor7e242562010-09-01 19:52:22 +00001112
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001113 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1114 return true;
1115
Douglas Gregor7e242562010-09-01 19:52:22 +00001116 return VisitDeclarationNameInfo(D->getNameInfo());
1117}
1118
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001119bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001120 // Visit nested-name-specifier.
Douglas Gregordb992412011-02-25 16:33:46 +00001121 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1122 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001123 return true;
Douglas Gregor0a35bce2010-09-01 03:07:18 +00001124
1125 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1126 D->getIdentLocation(), TU));
1127}
1128
Douglas Gregor7e242562010-09-01 19:52:22 +00001129bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001130 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001131 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1132 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001133 return true;
Douglas Gregordc355712011-02-25 00:36:19 +00001134 }
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001135
Douglas Gregor7e242562010-09-01 19:52:22 +00001136 return VisitDeclarationNameInfo(D->getNameInfo());
1137}
1138
1139bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1140 UnresolvedUsingTypenameDecl *D) {
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001141 // Visit nested-name-specifier.
Douglas Gregordc355712011-02-25 00:36:19 +00001142 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1143 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001144 return true;
1145
Douglas Gregor7e242562010-09-01 19:52:22 +00001146 return false;
1147}
1148
Douglas Gregor01829d32010-08-31 14:41:23 +00001149bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1150 switch (Name.getName().getNameKind()) {
1151 case clang::DeclarationName::Identifier:
1152 case clang::DeclarationName::CXXLiteralOperatorName:
1153 case clang::DeclarationName::CXXOperatorName:
1154 case clang::DeclarationName::CXXUsingDirective:
1155 return false;
1156
1157 case clang::DeclarationName::CXXConstructorName:
1158 case clang::DeclarationName::CXXDestructorName:
1159 case clang::DeclarationName::CXXConversionFunctionName:
1160 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1161 return Visit(TSInfo->getTypeLoc());
1162 return false;
1163
1164 case clang::DeclarationName::ObjCZeroArgSelector:
1165 case clang::DeclarationName::ObjCOneArgSelector:
1166 case clang::DeclarationName::ObjCMultiArgSelector:
1167 // FIXME: Per-identifier location info?
1168 return false;
1169 }
1170
1171 return false;
1172}
1173
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001174bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1175 SourceRange Range) {
1176 // FIXME: This whole routine is a hack to work around the lack of proper
1177 // source information in nested-name-specifiers (PR5791). Since we do have
1178 // a beginning source location, we can visit the first component of the
1179 // nested-name-specifier, if it's a single-token component.
1180 if (!NNS)
1181 return false;
1182
1183 // Get the first component in the nested-name-specifier.
1184 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1185 NNS = Prefix;
1186
1187 switch (NNS->getKind()) {
1188 case NestedNameSpecifier::Namespace:
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001189 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1190 TU));
1191
Douglas Gregor14aba762011-02-24 02:36:08 +00001192 case NestedNameSpecifier::NamespaceAlias:
1193 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1194 Range.getBegin(), TU));
1195
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001196 case NestedNameSpecifier::TypeSpec: {
1197 // If the type has a form where we know that the beginning of the source
1198 // range matches up with a reference cursor. Visit the appropriate reference
1199 // cursor.
John McCallf4c73712011-01-19 06:33:43 +00001200 const Type *T = NNS->getAsType();
Douglas Gregorc5ade2e2010-09-02 17:35:32 +00001201 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1202 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1203 if (const TagType *Tag = dyn_cast<TagType>(T))
1204 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1205 if (const TemplateSpecializationType *TST
1206 = dyn_cast<TemplateSpecializationType>(T))
1207 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1208 break;
1209 }
1210
1211 case NestedNameSpecifier::TypeSpecWithTemplate:
1212 case NestedNameSpecifier::Global:
1213 case NestedNameSpecifier::Identifier:
1214 break;
1215 }
1216
1217 return false;
1218}
1219
Douglas Gregordc355712011-02-25 00:36:19 +00001220bool
1221CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1222 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1223 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1224 Qualifiers.push_back(Qualifier);
1225
1226 while (!Qualifiers.empty()) {
1227 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1228 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1229 switch (NNS->getKind()) {
1230 case NestedNameSpecifier::Namespace:
1231 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001232 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001233 TU)))
1234 return true;
1235
1236 break;
1237
1238 case NestedNameSpecifier::NamespaceAlias:
1239 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001240 Q.getLocalBeginLoc(),
Douglas Gregordc355712011-02-25 00:36:19 +00001241 TU)))
1242 return true;
1243
1244 break;
1245
1246 case NestedNameSpecifier::TypeSpec:
1247 case NestedNameSpecifier::TypeSpecWithTemplate:
1248 if (Visit(Q.getTypeLoc()))
1249 return true;
1250
1251 break;
1252
1253 case NestedNameSpecifier::Global:
1254 case NestedNameSpecifier::Identifier:
1255 break;
1256 }
1257 }
1258
1259 return false;
1260}
1261
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001262bool CursorVisitor::VisitTemplateParameters(
1263 const TemplateParameterList *Params) {
1264 if (!Params)
1265 return false;
1266
1267 for (TemplateParameterList::const_iterator P = Params->begin(),
1268 PEnd = Params->end();
1269 P != PEnd; ++P) {
1270 if (Visit(MakeCXCursor(*P, TU)))
1271 return true;
1272 }
1273
1274 return false;
1275}
1276
Douglas Gregor0b36e612010-08-31 20:37:03 +00001277bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1278 switch (Name.getKind()) {
1279 case TemplateName::Template:
1280 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1281
1282 case TemplateName::OverloadedTemplate:
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001283 // Visit the overloaded template set.
1284 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1285 return true;
1286
Douglas Gregor0b36e612010-08-31 20:37:03 +00001287 return false;
1288
1289 case TemplateName::DependentTemplate:
1290 // FIXME: Visit nested-name-specifier.
1291 return false;
1292
1293 case TemplateName::QualifiedTemplate:
1294 // FIXME: Visit nested-name-specifier.
1295 return Visit(MakeCursorTemplateRef(
1296 Name.getAsQualifiedTemplateName()->getDecl(),
1297 Loc, TU));
Douglas Gregor1aee05d2011-01-15 06:45:20 +00001298
1299 case TemplateName::SubstTemplateTemplateParmPack:
1300 return Visit(MakeCursorTemplateRef(
1301 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1302 Loc, TU));
Douglas Gregor0b36e612010-08-31 20:37:03 +00001303 }
1304
1305 return false;
1306}
1307
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001308bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1309 switch (TAL.getArgument().getKind()) {
1310 case TemplateArgument::Null:
1311 case TemplateArgument::Integral:
Douglas Gregor87dd6972010-12-20 16:52:59 +00001312 case TemplateArgument::Pack:
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001313 return false;
1314
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001315 case TemplateArgument::Type:
1316 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1317 return Visit(TSInfo->getTypeLoc());
1318 return false;
1319
1320 case TemplateArgument::Declaration:
1321 if (Expr *E = TAL.getSourceDeclExpression())
1322 return Visit(MakeCXCursor(E, StmtParent, TU));
1323 return false;
1324
1325 case TemplateArgument::Expression:
1326 if (Expr *E = TAL.getSourceExpression())
1327 return Visit(MakeCXCursor(E, StmtParent, TU));
1328 return false;
1329
1330 case TemplateArgument::Template:
Douglas Gregora7fc9012011-01-05 18:58:31 +00001331 case TemplateArgument::TemplateExpansion:
Douglas Gregorb6744ef2011-03-02 17:09:35 +00001332 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1333 return true;
1334
Douglas Gregora7fc9012011-01-05 18:58:31 +00001335 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregor0b36e612010-08-31 20:37:03 +00001336 TAL.getTemplateNameLoc());
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001337 }
1338
1339 return false;
1340}
1341
Ted Kremeneka0536d82010-05-07 01:04:29 +00001342bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1343 return VisitDeclContext(D);
1344}
1345
Douglas Gregor01829d32010-08-31 14:41:23 +00001346bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1347 return Visit(TL.getUnqualifiedLoc());
1348}
1349
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001350bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00001351 ASTContext &Context = AU->getASTContext();
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001352
1353 // Some builtin types (such as Objective-C's "id", "sel", and
1354 // "Class") have associated declarations. Create cursors for those.
1355 QualType VisitType;
1356 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001357 case BuiltinType::Void:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001358 case BuiltinType::Bool:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001359 case BuiltinType::Char_U:
1360 case BuiltinType::UChar:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001361 case BuiltinType::Char16:
1362 case BuiltinType::Char32:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001363 case BuiltinType::UShort:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001364 case BuiltinType::UInt:
1365 case BuiltinType::ULong:
1366 case BuiltinType::ULongLong:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001367 case BuiltinType::UInt128:
1368 case BuiltinType::Char_S:
1369 case BuiltinType::SChar:
Chris Lattner3f59c972010-12-25 23:25:43 +00001370 case BuiltinType::WChar_U:
1371 case BuiltinType::WChar_S:
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001372 case BuiltinType::Short:
1373 case BuiltinType::Int:
1374 case BuiltinType::Long:
1375 case BuiltinType::LongLong:
1376 case BuiltinType::Int128:
1377 case BuiltinType::Float:
1378 case BuiltinType::Double:
1379 case BuiltinType::LongDouble:
1380 case BuiltinType::NullPtr:
1381 case BuiltinType::Overload:
1382 case BuiltinType::Dependent:
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001383 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001384
Ted Kremenekc4174cc2010-02-18 18:52:18 +00001385 case BuiltinType::ObjCId:
1386 VisitType = Context.getObjCIdType();
1387 break;
Ted Kremenek6b3b5142010-02-18 22:32:43 +00001388
1389 case BuiltinType::ObjCClass:
1390 VisitType = Context.getObjCClassType();
1391 break;
1392
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001393 case BuiltinType::ObjCSel:
1394 VisitType = Context.getObjCSelType();
1395 break;
1396 }
1397
1398 if (!VisitType.isNull()) {
1399 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001400 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001401 TU));
1402 }
1403
1404 return false;
1405}
1406
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00001407bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1408 return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
1409}
1410
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001411bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1412 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1413}
1414
1415bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1416 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1417}
1418
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001419bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00001420 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001421 // no context information with which we can match up the depth/index in the
1422 // type to the appropriate
1423 return false;
1424}
1425
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001426bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1427 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1428 return true;
1429
John McCallc12c5bb2010-05-15 11:32:37 +00001430 return false;
1431}
1432
1433bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1434 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1435 return true;
1436
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001437 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1438 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1439 TU)))
1440 return true;
1441 }
1442
1443 return false;
1444}
1445
1446bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCallc12c5bb2010-05-15 11:32:37 +00001447 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001448}
1449
Abramo Bagnara075f8f12010-12-10 16:29:40 +00001450bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1451 return Visit(TL.getInnerLoc());
1452}
1453
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001454bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1455 return Visit(TL.getPointeeLoc());
1456}
1457
1458bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1459 return Visit(TL.getPointeeLoc());
1460}
1461
1462bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1463 return Visit(TL.getPointeeLoc());
1464}
1465
1466bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001467 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001468}
1469
1470bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00001471 return Visit(TL.getPointeeLoc());
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001472}
1473
Douglas Gregor01829d32010-08-31 14:41:23 +00001474bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1475 bool SkipResultType) {
1476 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001477 return true;
1478
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001479 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek5dbacb42010-04-07 00:27:13 +00001480 if (Decl *D = TL.getArg(I))
1481 if (Visit(MakeCXCursor(D, TU)))
1482 return true;
Douglas Gregorf20dfbc2010-01-21 17:29:07 +00001483
1484 return false;
1485}
1486
1487bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1488 if (Visit(TL.getElementLoc()))
1489 return true;
1490
1491 if (Expr *Size = TL.getSizeExpr())
1492 return Visit(MakeCXCursor(Size, StmtParent, TU));
1493
1494 return false;
1495}
1496
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001497bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1498 TemplateSpecializationTypeLoc TL) {
Douglas Gregor0b36e612010-08-31 20:37:03 +00001499 // Visit the template name.
1500 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1501 TL.getTemplateNameLoc()))
1502 return true;
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00001503
1504 // Visit the template arguments.
1505 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1506 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1507 return true;
1508
1509 return false;
1510}
1511
Douglas Gregor2332c112010-01-21 20:48:56 +00001512bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1513 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1514}
1515
1516bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1517 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1518 return Visit(TSInfo->getTypeLoc());
1519
1520 return false;
1521}
1522
Douglas Gregor2494dd02011-03-01 01:34:45 +00001523bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1524 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1525 return true;
1526
1527 return false;
1528}
1529
Douglas Gregor94fdffa2011-03-01 20:11:18 +00001530bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1531 DependentTemplateSpecializationTypeLoc TL) {
1532 // Visit the nested-name-specifier, if there is one.
1533 if (TL.getQualifierLoc() &&
1534 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1535 return true;
1536
1537 // Visit the template arguments.
1538 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1539 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1540 return true;
1541
1542 return false;
1543}
1544
Douglas Gregor9e876872011-03-01 18:12:44 +00001545bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1546 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1547 return true;
1548
1549 return Visit(TL.getNamedTypeLoc());
1550}
1551
Douglas Gregor7536dd52010-12-20 02:24:11 +00001552bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1553 return Visit(TL.getPatternLoc());
1554}
1555
Ted Kremenek3064ef92010-08-27 21:34:58 +00001556bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregorc22b5ff2011-02-25 02:25:35 +00001557 // Visit the nested-name-specifier, if present.
1558 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1559 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1560 return true;
1561
Ted Kremenek3064ef92010-08-27 21:34:58 +00001562 if (D->isDefinition()) {
1563 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1564 E = D->bases_end(); I != E; ++I) {
1565 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1566 return true;
1567 }
1568 }
1569
1570 return VisitTagDecl(D);
1571}
1572
Ted Kremenek09dfa372010-02-18 05:46:33 +00001573bool CursorVisitor::VisitAttributes(Decl *D) {
Sean Huntcf807c42010-08-18 23:23:40 +00001574 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1575 i != e; ++i)
1576 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek09dfa372010-02-18 05:46:33 +00001577 return true;
1578
1579 return false;
1580}
1581
Ted Kremenekc0e1d922010-11-11 08:05:18 +00001582//===----------------------------------------------------------------------===//
1583// Data-recursive visitor methods.
1584//===----------------------------------------------------------------------===//
1585
Ted Kremenek28a71942010-11-13 00:36:47 +00001586namespace {
Ted Kremenek035dc412010-11-13 00:36:50 +00001587#define DEF_JOB(NAME, DATA, KIND)\
1588class NAME : public VisitorJob {\
1589public:\
1590 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1591 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenekf64d8032010-11-18 00:02:32 +00001592 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek035dc412010-11-13 00:36:50 +00001593};
1594
1595DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1596DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001597DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001598DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek60608ec2010-11-17 00:50:47 +00001599DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1600 ExplicitTemplateArgsVisitKind)
Douglas Gregor94d96292011-01-19 20:34:17 +00001601DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek035dc412010-11-13 00:36:50 +00001602#undef DEF_JOB
1603
1604class DeclVisit : public VisitorJob {
1605public:
1606 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1607 VisitorJob(parent, VisitorJob::DeclVisitKind,
1608 d, isFirst ? (void*) 1 : (void*) 0) {}
1609 static bool classof(const VisitorJob *VJ) {
Ted Kremenek82f3c502010-11-15 22:23:26 +00001610 return VJ->getKind() == DeclVisitKind;
Ted Kremenek035dc412010-11-13 00:36:50 +00001611 }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001612 Decl *get() const { return static_cast<Decl*>(data[0]); }
1613 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek035dc412010-11-13 00:36:50 +00001614};
Ted Kremenek035dc412010-11-13 00:36:50 +00001615class TypeLocVisit : public VisitorJob {
1616public:
1617 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1618 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1619 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1620
1621 static bool classof(const VisitorJob *VJ) {
1622 return VJ->getKind() == TypeLocVisitKind;
1623 }
1624
Ted Kremenek82f3c502010-11-15 22:23:26 +00001625 TypeLoc get() const {
Ted Kremenekf64d8032010-11-18 00:02:32 +00001626 QualType T = QualType::getFromOpaquePtr(data[0]);
1627 return TypeLoc(T, data[1]);
Ted Kremenek035dc412010-11-13 00:36:50 +00001628 }
1629};
1630
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001631class LabelRefVisit : public VisitorJob {
1632public:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001633 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1634 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001635 labelLoc.getPtrEncoding()) {}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001636
1637 static bool classof(const VisitorJob *VJ) {
1638 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1639 }
Chris Lattnerad8dcf42011-02-17 07:39:24 +00001640 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001641 SourceLocation getLoc() const {
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001642 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001643};
1644class NestedNameSpecifierVisit : public VisitorJob {
1645public:
1646 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1647 CXCursor parent)
1648 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001649 NS, R.getBegin().getPtrEncoding(),
1650 R.getEnd().getPtrEncoding()) {}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001651 static bool classof(const VisitorJob *VJ) {
1652 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1653 }
1654 NestedNameSpecifier *get() const {
1655 return static_cast<NestedNameSpecifier*>(data[0]);
1656 }
1657 SourceRange getSourceRange() const {
1658 SourceLocation A =
1659 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1660 SourceLocation B =
1661 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1662 return SourceRange(A, B);
1663 }
1664};
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001665
1666class NestedNameSpecifierLocVisit : public VisitorJob {
1667public:
1668 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1669 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1670 Qualifier.getNestedNameSpecifier(),
1671 Qualifier.getOpaqueData()) { }
1672
1673 static bool classof(const VisitorJob *VJ) {
1674 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1675 }
1676
1677 NestedNameSpecifierLoc get() const {
1678 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1679 data[1]);
1680 }
1681};
1682
Ted Kremenekf64d8032010-11-18 00:02:32 +00001683class DeclarationNameInfoVisit : public VisitorJob {
1684public:
1685 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1686 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1687 static bool classof(const VisitorJob *VJ) {
1688 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1689 }
1690 DeclarationNameInfo get() const {
1691 Stmt *S = static_cast<Stmt*>(data[0]);
1692 switch (S->getStmtClass()) {
1693 default:
1694 llvm_unreachable("Unhandled Stmt");
1695 case Stmt::CXXDependentScopeMemberExprClass:
1696 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1697 case Stmt::DependentScopeDeclRefExprClass:
1698 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1699 }
1700 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001701};
Ted Kremenekcdba6592010-11-18 00:42:18 +00001702class MemberRefVisit : public VisitorJob {
1703public:
1704 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1705 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskindec09842011-01-18 02:00:16 +00001706 L.getPtrEncoding()) {}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1709 }
1710 FieldDecl *get() const {
1711 return static_cast<FieldDecl*>(data[0]);
1712 }
1713 SourceLocation getLoc() const {
1714 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1715 }
1716};
Ted Kremenek28a71942010-11-13 00:36:47 +00001717class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1718 VisitorWorkList &WL;
1719 CXCursor Parent;
1720public:
1721 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1722 : WL(wl), Parent(parent) {}
1723
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001724 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001725 void VisitBlockExpr(BlockExpr *B);
Ted Kremenek28a71942010-11-13 00:36:47 +00001726 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenek083c7e22010-11-13 05:38:03 +00001727 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001728 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenekf64d8032010-11-18 00:02:32 +00001729 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001730 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001731 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001732 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001733 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001734 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001735 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek55b933a2010-11-17 00:50:36 +00001736 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001737 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001738 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek035dc412010-11-13 00:36:50 +00001739 void VisitDeclStmt(DeclStmt *S);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001740 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001741 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001742 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1743 void VisitForStmt(ForStmt *FS);
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001744 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenek28a71942010-11-13 00:36:47 +00001745 void VisitIfStmt(IfStmt *If);
1746 void VisitInitListExpr(InitListExpr *IE);
1747 void VisitMemberExpr(MemberExpr *M);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001748 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek73d15c42010-11-13 01:09:29 +00001749 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001750 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1751 void VisitOverloadExpr(OverloadExpr *E);
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001752 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001753 void VisitStmt(Stmt *S);
1754 void VisitSwitchStmt(SwitchStmt *S);
1755 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek2939b6f2010-11-17 00:50:50 +00001756 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet6ad6f282010-12-07 00:08:36 +00001757 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
Ted Kremenek28a71942010-11-13 00:36:47 +00001758 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenek9d3bf792010-11-17 00:50:43 +00001759 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor94d96292011-01-19 20:34:17 +00001760 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregoree8aff02011-01-04 17:33:58 +00001761
Ted Kremenek28a71942010-11-13 00:36:47 +00001762private:
Ted Kremenekf64d8032010-11-18 00:02:32 +00001763 void AddDeclarationNameInfo(Stmt *S);
1764 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001765 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek60608ec2010-11-17 00:50:47 +00001766 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001767 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenek28a71942010-11-13 00:36:47 +00001768 void AddStmt(Stmt *S);
Ted Kremenek035dc412010-11-13 00:36:50 +00001769 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenek28a71942010-11-13 00:36:47 +00001770 void AddTypeLoc(TypeSourceInfo *TI);
1771 void EnqueueChildren(Stmt *S);
1772};
1773} // end anonyous namespace
1774
Ted Kremenekf64d8032010-11-18 00:02:32 +00001775void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1776 // 'S' should always be non-null, since it comes from the
1777 // statement we are visiting.
1778 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1779}
1780void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1781 SourceRange R) {
1782 if (N)
1783 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1784}
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001785
1786void
1787EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1788 if (Qualifier)
1789 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1790}
1791
Ted Kremenek28a71942010-11-13 00:36:47 +00001792void EnqueueVisitor::AddStmt(Stmt *S) {
1793 if (S)
1794 WL.push_back(StmtVisit(S, Parent));
1795}
Ted Kremenek035dc412010-11-13 00:36:50 +00001796void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001797 if (D)
Ted Kremenek035dc412010-11-13 00:36:50 +00001798 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenek28a71942010-11-13 00:36:47 +00001799}
Ted Kremenek60608ec2010-11-17 00:50:47 +00001800void EnqueueVisitor::
1801 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1802 if (A)
1803 WL.push_back(ExplicitTemplateArgsVisit(
1804 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1805}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001806void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1807 if (D)
1808 WL.push_back(MemberRefVisit(D, L, Parent));
1809}
Ted Kremenek28a71942010-11-13 00:36:47 +00001810void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1811 if (TI)
1812 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1813 }
1814void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremeneka6b70432010-11-12 21:34:09 +00001815 unsigned size = WL.size();
John McCall7502c1d2011-02-13 04:07:26 +00001816 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenek28a71942010-11-13 00:36:47 +00001817 AddStmt(*Child);
Ted Kremeneka6b70432010-11-12 21:34:09 +00001818 }
1819 if (size == WL.size())
1820 return;
1821 // Now reverse the entries we just added. This will match the DFS
1822 // ordering performed by the worklist.
1823 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1824 std::reverse(I, E);
1825}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001826void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1827 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1828}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001829void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1830 AddDecl(B->getBlockDecl());
1831}
Ted Kremenek28a71942010-11-13 00:36:47 +00001832void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1833 EnqueueChildren(E);
1834 AddTypeLoc(E->getTypeSourceInfo());
1835}
Ted Kremenek083c7e22010-11-13 05:38:03 +00001836void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1837 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1838 E = S->body_rend(); I != E; ++I) {
1839 AddStmt(*I);
1840 }
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001841}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001842void EnqueueVisitor::
1843VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1844 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1845 AddDeclarationNameInfo(E);
Douglas Gregor7c3179c2011-02-28 18:50:33 +00001846 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1847 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekf64d8032010-11-18 00:02:32 +00001848 if (!E->isImplicitAccess())
1849 AddStmt(E->getBase());
1850}
Ted Kremenek11b8e3e2010-11-13 05:55:53 +00001851void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1852 // Enqueue the initializer or constructor arguments.
1853 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1854 AddStmt(E->getConstructorArg(I-1));
1855 // Enqueue the array size, if any.
1856 AddStmt(E->getArraySize());
1857 // Enqueue the allocated type.
1858 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1859 // Enqueue the placement arguments.
1860 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1861 AddStmt(E->getPlacementArg(I-1));
1862}
Ted Kremenek28a71942010-11-13 00:36:47 +00001863void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenek8b8d8c92010-11-13 05:55:56 +00001864 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1865 AddStmt(CE->getArg(I-1));
Ted Kremenek28a71942010-11-13 00:36:47 +00001866 AddStmt(CE->getCallee());
1867 AddStmt(CE->getArg(0));
1868}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001869void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1870 // Visit the name of the type being destroyed.
1871 AddTypeLoc(E->getDestroyedTypeInfo());
1872 // Visit the scope type that looks disturbingly like the nested-name-specifier
1873 // but isn't.
1874 AddTypeLoc(E->getScopeTypeInfo());
1875 // Visit the nested-name-specifier.
Douglas Gregorf3db29f2011-02-25 18:19:59 +00001876 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1877 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenekcdba6592010-11-18 00:42:18 +00001878 // Visit base expression.
1879 AddStmt(E->getBase());
1880}
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00001881void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1882 AddTypeLoc(E->getTypeSourceInfo());
1883}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001884void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1885 EnqueueChildren(E);
1886 AddTypeLoc(E->getTypeSourceInfo());
1887}
Ted Kremenekb8dd1ca2010-11-17 00:50:41 +00001888void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1889 EnqueueChildren(E);
1890 if (E->isTypeOperand())
1891 AddTypeLoc(E->getTypeOperandSourceInfo());
1892}
Ted Kremenek55b933a2010-11-17 00:50:36 +00001893
1894void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1895 *E) {
1896 EnqueueChildren(E);
1897 AddTypeLoc(E->getTypeSourceInfo());
1898}
Ted Kremenek1e7e8772010-11-17 00:50:52 +00001899void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1900 EnqueueChildren(E);
1901 if (E->isTypeOperand())
1902 AddTypeLoc(E->getTypeOperandSourceInfo());
1903}
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001904void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00001905 if (DR->hasExplicitTemplateArgs()) {
1906 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1907 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00001908 WL.push_back(DeclRefExprParts(DR, Parent));
1909}
Ted Kremenekf64d8032010-11-18 00:02:32 +00001910void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1911 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1912 AddDeclarationNameInfo(E);
Douglas Gregor00cf3cc2011-02-25 20:49:16 +00001913 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenekf64d8032010-11-18 00:02:32 +00001914}
Ted Kremenek035dc412010-11-13 00:36:50 +00001915void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1916 unsigned size = WL.size();
1917 bool isFirst = true;
1918 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1919 D != DEnd; ++D) {
1920 AddDecl(*D, isFirst);
1921 isFirst = false;
1922 }
1923 if (size == WL.size())
1924 return;
1925 // Now reverse the entries we just added. This will match the DFS
1926 // ordering performed by the worklist.
1927 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1928 std::reverse(I, E);
1929}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001930void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1931 AddStmt(E->getInit());
1932 typedef DesignatedInitExpr::Designator Designator;
1933 for (DesignatedInitExpr::reverse_designators_iterator
1934 D = E->designators_rbegin(), DEnd = E->designators_rend();
1935 D != DEnd; ++D) {
1936 if (D->isFieldDesignator()) {
1937 if (FieldDecl *Field = D->getField())
1938 AddMemberRef(Field, D->getFieldLoc());
1939 continue;
1940 }
1941 if (D->isArrayDesignator()) {
1942 AddStmt(E->getArrayIndex(*D));
1943 continue;
1944 }
1945 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1946 AddStmt(E->getArrayRangeEnd(*D));
1947 AddStmt(E->getArrayRangeStart(*D));
1948 }
1949}
Ted Kremenek28a71942010-11-13 00:36:47 +00001950void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1951 EnqueueChildren(E);
1952 AddTypeLoc(E->getTypeInfoAsWritten());
1953}
1954void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1955 AddStmt(FS->getBody());
1956 AddStmt(FS->getInc());
1957 AddStmt(FS->getCond());
1958 AddDecl(FS->getConditionVariable());
1959 AddStmt(FS->getInit());
1960}
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00001961void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1962 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1963}
Ted Kremenek28a71942010-11-13 00:36:47 +00001964void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
1965 AddStmt(If->getElse());
1966 AddStmt(If->getThen());
1967 AddStmt(If->getCond());
1968 AddDecl(If->getConditionVariable());
1969}
1970void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
1971 // We care about the syntactic form of the initializer list, only.
1972 if (InitListExpr *Syntactic = IE->getSyntacticForm())
1973 IE = Syntactic;
1974 EnqueueChildren(IE);
1975}
1976void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor89629a72010-11-17 17:15:08 +00001977 WL.push_back(MemberExprParts(M, Parent));
1978
1979 // If the base of the member access expression is an implicit 'this', don't
1980 // visit it.
1981 // FIXME: If we ever want to show these implicit accesses, this will be
1982 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor75e85042011-03-02 21:06:53 +00001983 if (!M->isImplicitAccess())
1984 AddStmt(M->getBase());
Ted Kremenek28a71942010-11-13 00:36:47 +00001985}
Ted Kremenek73d15c42010-11-13 01:09:29 +00001986void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
1987 AddTypeLoc(E->getEncodedTypeSourceInfo());
1988}
Ted Kremenek28a71942010-11-13 00:36:47 +00001989void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
1990 EnqueueChildren(M);
1991 AddTypeLoc(M->getClassReceiverTypeInfo());
1992}
Ted Kremenekcdba6592010-11-18 00:42:18 +00001993void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
1994 // Visit the components of the offsetof expression.
1995 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
1996 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
1997 const OffsetOfNode &Node = E->getComponent(I-1);
1998 switch (Node.getKind()) {
1999 case OffsetOfNode::Array:
2000 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2001 break;
2002 case OffsetOfNode::Field:
2003 AddMemberRef(Node.getField(), Node.getRange().getEnd());
2004 break;
2005 case OffsetOfNode::Identifier:
2006 case OffsetOfNode::Base:
2007 continue;
2008 }
2009 }
2010 // Visit the type into which we're computing the offset.
2011 AddTypeLoc(E->getTypeSourceInfo());
2012}
Ted Kremenek28a71942010-11-13 00:36:47 +00002013void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek60608ec2010-11-17 00:50:47 +00002014 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenek60458782010-11-12 21:34:16 +00002015 WL.push_back(OverloadExprParts(E, Parent));
2016}
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00002017void EnqueueVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
2018 EnqueueChildren(E);
2019 if (E->isArgumentType())
2020 AddTypeLoc(E->getArgumentTypeInfo());
2021}
Ted Kremenek28a71942010-11-13 00:36:47 +00002022void EnqueueVisitor::VisitStmt(Stmt *S) {
2023 EnqueueChildren(S);
2024}
2025void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2026 AddStmt(S->getBody());
2027 AddStmt(S->getCond());
2028 AddDecl(S->getConditionVariable());
2029}
Ted Kremenekfafa75a2010-11-17 00:50:39 +00002030
Ted Kremenek28a71942010-11-13 00:36:47 +00002031void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2032 AddStmt(W->getBody());
2033 AddStmt(W->getCond());
2034 AddDecl(W->getConditionVariable());
2035}
Ted Kremenek2939b6f2010-11-17 00:50:50 +00002036void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2037 AddTypeLoc(E->getQueriedTypeSourceInfo());
2038}
Francois Pichet6ad6f282010-12-07 00:08:36 +00002039
2040void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet6ad6f282010-12-07 00:08:36 +00002041 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichet0a03a3f2010-12-08 09:11:05 +00002042 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet6ad6f282010-12-07 00:08:36 +00002043}
2044
Ted Kremenek28a71942010-11-13 00:36:47 +00002045void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2046 VisitOverloadExpr(U);
2047 if (!U->isImplicitAccess())
2048 AddStmt(U->getBase());
2049}
Ted Kremenek9d3bf792010-11-17 00:50:43 +00002050void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2051 AddStmt(E->getSubExpr());
2052 AddTypeLoc(E->getWrittenTypeInfo());
2053}
Douglas Gregor94d96292011-01-19 20:34:17 +00002054void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2055 WL.push_back(SizeOfPackExprParts(E, Parent));
2056}
Ted Kremenek60458782010-11-12 21:34:16 +00002057
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002058void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenek28a71942010-11-13 00:36:47 +00002059 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002060}
2061
2062bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2063 if (RegionOfInterest.isValid()) {
2064 SourceRange Range = getRawCursorExtent(C);
2065 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2066 return false;
2067 }
2068 return true;
2069}
2070
2071bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2072 while (!WL.empty()) {
2073 // Dequeue the worklist item.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002074 VisitorJob LI = WL.back();
2075 WL.pop_back();
2076
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002077 // Set the Parent field, then back to its old value once we're done.
2078 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2079
2080 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00002081 case VisitorJob::DeclVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002082 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenekf1107452010-11-12 18:26:56 +00002083 if (!D)
2084 continue;
2085
2086 // For now, perform default visitation for Decls.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002087 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenekf1107452010-11-12 18:26:56 +00002088 return true;
2089
2090 continue;
2091 }
Ted Kremenek60608ec2010-11-17 00:50:47 +00002092 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2093 const ExplicitTemplateArgumentList *ArgList =
2094 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2095 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2096 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2097 Arg != ArgEnd; ++Arg) {
2098 if (VisitTemplateArgumentLoc(*Arg))
2099 return true;
2100 }
2101 continue;
2102 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002103 case VisitorJob::TypeLocVisitKind: {
2104 // Perform default visitation for TypeLocs.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002105 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002106 return true;
2107 continue;
2108 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002109 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002110 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremeneke7455012011-02-23 04:54:51 +00002111 if (LabelStmt *stmt = LS->getStmt()) {
2112 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2113 TU))) {
2114 return true;
2115 }
2116 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002117 continue;
2118 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002119
Ted Kremenekf64d8032010-11-18 00:02:32 +00002120 case VisitorJob::NestedNameSpecifierVisitKind: {
2121 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2122 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2123 return true;
2124 continue;
2125 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002126
2127 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2128 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2129 if (VisitNestedNameSpecifierLoc(V->get()))
2130 return true;
2131 continue;
2132 }
2133
Ted Kremenekf64d8032010-11-18 00:02:32 +00002134 case VisitorJob::DeclarationNameInfoVisitKind: {
2135 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2136 ->get()))
2137 return true;
2138 continue;
2139 }
Ted Kremenekcdba6592010-11-18 00:42:18 +00002140 case VisitorJob::MemberRefVisitKind: {
2141 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2142 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2143 return true;
2144 continue;
2145 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002146 case VisitorJob::StmtVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002147 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002148 if (!S)
2149 continue;
2150
Ted Kremenekf1107452010-11-12 18:26:56 +00002151 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002152 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenekcdba6592010-11-18 00:42:18 +00002153 if (!IsInRegionOfInterest(Cursor))
2154 continue;
2155 switch (Visitor(Cursor, Parent, ClientData)) {
2156 case CXChildVisit_Break: return true;
2157 case CXChildVisit_Continue: break;
2158 case CXChildVisit_Recurse:
2159 EnqueueWorkList(WL, S);
Ted Kremenek82f3c502010-11-15 22:23:26 +00002160 break;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002161 }
Ted Kremenek82f3c502010-11-15 22:23:26 +00002162 continue;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002163 }
2164 case VisitorJob::MemberExprPartsKind: {
2165 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002166 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002167
2168 // Visit the nested-name-specifier
Douglas Gregor40d96a62011-02-28 21:54:11 +00002169 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002171 return true;
2172
2173 // Visit the declaration name.
2174 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2175 return true;
2176
2177 // Visit the explicitly-specified template arguments, if any.
2178 if (M->hasExplicitTemplateArgs()) {
2179 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2180 *ArgEnd = Arg + M->getNumTemplateArgs();
2181 Arg != ArgEnd; ++Arg) {
2182 if (VisitTemplateArgumentLoc(*Arg))
2183 return true;
2184 }
2185 }
2186 continue;
2187 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002188 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002189 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002190 // Visit nested-name-specifier, if present.
Douglas Gregor40d96a62011-02-28 21:54:11 +00002191 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2192 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002193 return true;
2194 // Visit declaration name.
2195 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2196 return true;
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002197 continue;
2198 }
Ted Kremenek60458782010-11-12 21:34:16 +00002199 case VisitorJob::OverloadExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002200 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenek60458782010-11-12 21:34:16 +00002201 // Visit the nested-name-specifier.
Douglas Gregor4c9be892011-02-28 20:01:57 +00002202 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2203 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek60458782010-11-12 21:34:16 +00002204 return true;
2205 // Visit the declaration name.
2206 if (VisitDeclarationNameInfo(O->getNameInfo()))
2207 return true;
2208 // Visit the overloaded declaration reference.
2209 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2210 return true;
Ted Kremenek60458782010-11-12 21:34:16 +00002211 continue;
2212 }
Douglas Gregor94d96292011-01-19 20:34:17 +00002213 case VisitorJob::SizeOfPackExprPartsKind: {
2214 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2215 NamedDecl *Pack = E->getPack();
2216 if (isa<TemplateTypeParmDecl>(Pack)) {
2217 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2218 E->getPackLoc(), TU)))
2219 return true;
2220
2221 continue;
2222 }
2223
2224 if (isa<TemplateTemplateParmDecl>(Pack)) {
2225 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2226 E->getPackLoc(), TU)))
2227 return true;
2228
2229 continue;
2230 }
2231
2232 // Non-type template parameter packs and function parameter packs are
2233 // treated like DeclRefExpr cursors.
2234 continue;
2235 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002236 }
2237 }
2238 return false;
2239}
2240
Ted Kremenekcdba6592010-11-18 00:42:18 +00002241bool CursorVisitor::Visit(Stmt *S) {
Ted Kremenekd1ded662010-11-15 23:31:32 +00002242 VisitorWorkList *WL = 0;
2243 if (!WorkListFreeList.empty()) {
2244 WL = WorkListFreeList.back();
2245 WL->clear();
2246 WorkListFreeList.pop_back();
2247 }
2248 else {
2249 WL = new VisitorWorkList();
2250 WorkListCache.push_back(WL);
2251 }
2252 EnqueueWorkList(*WL, S);
2253 bool result = RunVisitorWorkList(*WL);
2254 WorkListFreeList.push_back(WL);
2255 return result;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002256}
2257
2258//===----------------------------------------------------------------------===//
2259// Misc. API hooks.
2260//===----------------------------------------------------------------------===//
2261
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002262static llvm::sys::Mutex EnableMultithreadingMutex;
2263static bool EnabledMultithreading;
2264
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002265extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002266CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2267 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002268 // Disable pretty stack trace functionality, which will otherwise be a very
2269 // poor citizen of the world and set up all sorts of signal handlers.
2270 llvm::DisablePrettyStackTrace = true;
2271
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002272 // We use crash recovery to make some of our APIs more reliable, implicitly
2273 // enable it.
2274 llvm::CrashRecoveryContext::Enable();
2275
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002276 // Enable support for multithreading in LLVM.
2277 {
2278 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2279 if (!EnabledMultithreading) {
2280 llvm::llvm_start_multithreaded();
2281 EnabledMultithreading = true;
2282 }
2283 }
2284
Douglas Gregora030b7c2010-01-22 20:35:53 +00002285 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002286 if (excludeDeclarationsFromPCH)
2287 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002288 if (displayDiagnostics)
2289 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002290 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002291}
2292
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002293void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002294 if (CIdx)
2295 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002296}
2297
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002298CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002299 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002300 if (!CIdx)
2301 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002302
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002303 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002304 FileSystemOptions FileSystemOpts;
2305 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002306
Douglas Gregor28019772010-04-05 23:52:57 +00002307 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremeneka60ed472010-11-16 08:15:36 +00002308 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002309 CXXIdx->getOnlyLocalDecls(),
2310 0, 0, true);
Ted Kremeneka60ed472010-11-16 08:15:36 +00002311 return MakeCXTranslationUnit(TU);
Steve Naroff600866c2009-08-27 19:51:58 +00002312}
2313
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002314unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002315 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002316 CXTranslationUnit_CacheCompletionResults |
2317 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002318}
2319
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002320CXTranslationUnit
2321clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2322 const char *source_filename,
2323 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002324 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002325 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002326 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor5a430212010-07-21 18:52:53 +00002327 return clang_parseTranslationUnit(CIdx, source_filename,
2328 command_line_args, num_command_line_args,
2329 unsaved_files, num_unsaved_files,
2330 CXTranslationUnit_DetailedPreprocessingRecord);
2331}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002332
2333struct ParseTranslationUnitInfo {
2334 CXIndex CIdx;
2335 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002336 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002337 int num_command_line_args;
2338 struct CXUnsavedFile *unsaved_files;
2339 unsigned num_unsaved_files;
2340 unsigned options;
2341 CXTranslationUnit result;
2342};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002343static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002344 ParseTranslationUnitInfo *PTUI =
2345 static_cast<ParseTranslationUnitInfo*>(UserData);
2346 CXIndex CIdx = PTUI->CIdx;
2347 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002348 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002349 int num_command_line_args = PTUI->num_command_line_args;
2350 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2351 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2352 unsigned options = PTUI->options;
2353 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002354
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002355 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002356 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002357
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002358 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2359
Douglas Gregor44c181a2010-07-23 00:33:23 +00002360 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002361 bool CompleteTranslationUnit
2362 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002363 bool CacheCodeCompetionResults
2364 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002365 bool CXXPrecompilePreamble
2366 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2367 bool CXXChainedPCH
2368 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002369
Douglas Gregor5352ac02010-01-28 00:27:43 +00002370 // Configure the diagnostics.
2371 DiagnosticOptions DiagOpts;
Douglas Gregor28019772010-04-05 23:52:57 +00002372 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Douglas Gregor0b53cf82011-01-19 01:02:47 +00002373 Diags = CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2374 command_line_args);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002375
Douglas Gregor4db64a42010-01-23 00:14:00 +00002376 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2377 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002378 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002379 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002380 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregor4db64a42010-01-23 00:14:00 +00002381 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2382 Buffer));
2383 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002384
Douglas Gregorb10daed2010-10-11 16:52:23 +00002385 llvm::SmallVector<const char *, 16> Args;
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002386
Ted Kremenek139ba862009-10-22 00:03:57 +00002387 // The 'source_filename' argument is optional. If the caller does not
2388 // specify it then it is assumed that the source file is specified
2389 // in the actual argument list.
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002390 if (source_filename)
Douglas Gregorb10daed2010-10-11 16:52:23 +00002391 Args.push_back(source_filename);
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002392
2393 // Since the Clang C library is primarily used by batch tools dealing with
2394 // (often very broken) source code, where spell-checking can have a
2395 // significant negative impact on performance (particularly when
2396 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002397 // Only do this if we haven't found a spell-checking-related argument.
2398 bool FoundSpellCheckingArgument = false;
2399 for (int I = 0; I != num_command_line_args; ++I) {
2400 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2401 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2402 FoundSpellCheckingArgument = true;
2403 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002404 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002405 }
2406 if (!FoundSpellCheckingArgument)
2407 Args.push_back("-fno-spell-checking");
2408
2409 Args.insert(Args.end(), command_line_args,
2410 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002411
Douglas Gregor44c181a2010-07-23 00:33:23 +00002412 // Do we need the detailed preprocessing record?
2413 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002414 Args.push_back("-Xclang");
2415 Args.push_back("-detailed-preprocessing-record");
Douglas Gregor44c181a2010-07-23 00:33:23 +00002416 }
2417
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002418 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002419 llvm::OwningPtr<ASTUnit> Unit(
2420 ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
2421 Diags,
2422 CXXIdx->getClangResourcesPath(),
2423 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002424 /*CaptureDiagnostics=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002425 RemappedFiles.data(),
2426 RemappedFiles.size(),
Argyrios Kyrtzidis299a4a92011-03-08 23:35:24 +00002427 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002428 PrecompilePreamble,
2429 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002430 CacheCodeCompetionResults,
2431 CXXPrecompilePreamble,
2432 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002433
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002434 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002435 // Make sure to check that 'Unit' is non-NULL.
2436 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2437 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2438 DEnd = Unit->stored_diag_end();
2439 D != DEnd; ++D) {
2440 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2441 CXString Msg = clang_formatDiagnostic(&Diag,
2442 clang_defaultDiagnosticDisplayOptions());
2443 fprintf(stderr, "%s\n", clang_getCString(Msg));
2444 clang_disposeString(Msg);
2445 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002446#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002447 // On Windows, force a flush, since there may be multiple copies of
2448 // stderr and stdout in the file system, all with different buffers
2449 // but writing to the same device.
2450 fflush(stderr);
2451#endif
2452 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002453 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002454
Ted Kremeneka60ed472010-11-16 08:15:36 +00002455 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002456}
2457CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2458 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002459 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002460 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002461 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002462 unsigned num_unsaved_files,
2463 unsigned options) {
2464 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002465 num_command_line_args, unsaved_files,
2466 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002467 llvm::CrashRecoveryContext CRC;
2468
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002469 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002470 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2471 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2472 fprintf(stderr, " 'command_line_args' : [");
2473 for (int i = 0; i != num_command_line_args; ++i) {
2474 if (i)
2475 fprintf(stderr, ", ");
2476 fprintf(stderr, "'%s'", command_line_args[i]);
2477 }
2478 fprintf(stderr, "],\n");
2479 fprintf(stderr, " 'unsaved_files' : [");
2480 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2481 if (i)
2482 fprintf(stderr, ", ");
2483 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2484 unsaved_files[i].Length);
2485 }
2486 fprintf(stderr, "],\n");
2487 fprintf(stderr, " 'options' : %d,\n", options);
2488 fprintf(stderr, "}\n");
2489
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002490 return 0;
2491 }
2492
2493 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002494}
2495
Douglas Gregor19998442010-08-13 15:35:05 +00002496unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2497 return CXSaveTranslationUnit_None;
2498}
2499
2500int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2501 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002502 if (!TU)
2503 return 1;
2504
Ted Kremeneka60ed472010-11-16 08:15:36 +00002505 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002506}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002507
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002508void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002509 if (CTUnit) {
2510 // If the translation unit has been marked as unsafe to free, just discard
2511 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002512 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002513 return;
2514
Ted Kremeneka60ed472010-11-16 08:15:36 +00002515 delete static_cast<ASTUnit *>(CTUnit->TUData);
2516 disposeCXStringPool(CTUnit->StringPool);
2517 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002518 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002519}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002520
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002521unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2522 return CXReparse_None;
2523}
2524
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002525struct ReparseTranslationUnitInfo {
2526 CXTranslationUnit TU;
2527 unsigned num_unsaved_files;
2528 struct CXUnsavedFile *unsaved_files;
2529 unsigned options;
2530 int result;
2531};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002532
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002533static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002534 ReparseTranslationUnitInfo *RTUI =
2535 static_cast<ReparseTranslationUnitInfo*>(UserData);
2536 CXTranslationUnit TU = RTUI->TU;
2537 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2538 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2539 unsigned options = RTUI->options;
2540 (void) options;
2541 RTUI->result = 1;
2542
Douglas Gregorabc563f2010-07-19 21:46:24 +00002543 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002544 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002545
Ted Kremeneka60ed472010-11-16 08:15:36 +00002546 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002547 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002548
2549 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2550 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2551 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2552 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002553 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002554 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2555 Buffer));
2556 }
2557
Douglas Gregor593b0c12010-09-23 18:47:53 +00002558 if (!CXXUnit->Reparse(RemappedFiles.data(), RemappedFiles.size()))
2559 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002560}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002561
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002562int clang_reparseTranslationUnit(CXTranslationUnit TU,
2563 unsigned num_unsaved_files,
2564 struct CXUnsavedFile *unsaved_files,
2565 unsigned options) {
2566 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2567 options, 0 };
2568 llvm::CrashRecoveryContext CRC;
2569
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002570 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002571 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002572 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002573 return 1;
2574 }
2575
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002576
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002577 return RTUI.result;
2578}
2579
Douglas Gregordf95a132010-08-09 20:45:32 +00002580
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002581CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002582 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002583 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002584
Ted Kremeneka60ed472010-11-16 08:15:36 +00002585 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002586 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002587}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002588
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002589CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002590 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002591 return Result;
2592}
2593
Ted Kremenekfb480492010-01-13 21:46:36 +00002594} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002595
Ted Kremenekfb480492010-01-13 21:46:36 +00002596//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002597// CXSourceLocation and CXSourceRange Operations.
2598//===----------------------------------------------------------------------===//
2599
Douglas Gregorb9790342010-01-22 21:44:22 +00002600extern "C" {
2601CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002602 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002603 return Result;
2604}
2605
2606unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002607 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2608 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2609 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002610}
2611
2612CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2613 CXFile file,
2614 unsigned line,
2615 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002616 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002617 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002618
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002619 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002620 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002621 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002622 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002623 = CXXUnit->getSourceManager().getLocation(File, line, column);
2624 if (SLoc.isInvalid()) {
2625 if (Logging)
2626 llvm::errs() << "clang_getLocation(\"" << File->getName()
2627 << "\", " << line << ", " << column << ") = invalid\n";
2628 return clang_getNullLocation();
2629 }
2630
2631 if (Logging)
2632 llvm::errs() << "clang_getLocation(\"" << File->getName()
2633 << "\", " << line << ", " << column << ") = "
2634 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002635
2636 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2637}
2638
2639CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2640 CXFile file,
2641 unsigned offset) {
2642 if (!tu || !file)
2643 return clang_getNullLocation();
2644
Ted Kremeneka60ed472010-11-16 08:15:36 +00002645 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002646 SourceLocation Start
2647 = CXXUnit->getSourceManager().getLocation(
2648 static_cast<const FileEntry *>(file),
2649 1, 1);
2650 if (Start.isInvalid()) return clang_getNullLocation();
2651
2652 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2653
2654 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002655
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002656 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002657}
2658
Douglas Gregor5352ac02010-01-28 00:27:43 +00002659CXSourceRange clang_getNullRange() {
2660 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2661 return Result;
2662}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002663
Douglas Gregor5352ac02010-01-28 00:27:43 +00002664CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2665 if (begin.ptr_data[0] != end.ptr_data[0] ||
2666 begin.ptr_data[1] != end.ptr_data[1])
2667 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002668
2669 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002670 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002671 return Result;
2672}
2673
Douglas Gregor46766dc2010-01-26 19:19:08 +00002674void clang_getInstantiationLocation(CXSourceLocation location,
2675 CXFile *file,
2676 unsigned *line,
2677 unsigned *column,
2678 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002679 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2680
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002681 if (!location.ptr_data[0] || Loc.isInvalid()) {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002682 if (file)
2683 *file = 0;
2684 if (line)
2685 *line = 0;
2686 if (column)
2687 *column = 0;
2688 if (offset)
2689 *offset = 0;
2690 return;
2691 }
2692
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002693 const SourceManager &SM =
2694 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002695 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002696
2697 if (file)
2698 *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));
2699 if (line)
2700 *line = SM.getInstantiationLineNumber(InstLoc);
2701 if (column)
2702 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002703 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002704 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002705}
2706
Douglas Gregora9b06d42010-11-09 06:24:54 +00002707void clang_getSpellingLocation(CXSourceLocation location,
2708 CXFile *file,
2709 unsigned *line,
2710 unsigned *column,
2711 unsigned *offset) {
2712 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2713
2714 if (!location.ptr_data[0] || Loc.isInvalid()) {
2715 if (file)
2716 *file = 0;
2717 if (line)
2718 *line = 0;
2719 if (column)
2720 *column = 0;
2721 if (offset)
2722 *offset = 0;
2723 return;
2724 }
2725
2726 const SourceManager &SM =
2727 *static_cast<const SourceManager*>(location.ptr_data[0]);
2728 SourceLocation SpellLoc = Loc;
2729 if (SpellLoc.isMacroID()) {
2730 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2731 if (SimpleSpellingLoc.isFileID() &&
2732 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2733 SpellLoc = SimpleSpellingLoc;
2734 else
2735 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2736 }
2737
2738 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2739 FileID FID = LocInfo.first;
2740 unsigned FileOffset = LocInfo.second;
2741
2742 if (file)
2743 *file = (void *)SM.getFileEntryForID(FID);
2744 if (line)
2745 *line = SM.getLineNumber(FID, FileOffset);
2746 if (column)
2747 *column = SM.getColumnNumber(FID, FileOffset);
2748 if (offset)
2749 *offset = FileOffset;
2750}
2751
Douglas Gregor1db19de2010-01-19 21:36:55 +00002752CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002753 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002754 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002755 return Result;
2756}
2757
2758CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002759 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002760 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002761 return Result;
2762}
2763
Douglas Gregorb9790342010-01-22 21:44:22 +00002764} // end: extern "C"
2765
Douglas Gregor1db19de2010-01-19 21:36:55 +00002766//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002767// CXFile Operations.
2768//===----------------------------------------------------------------------===//
2769
2770extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002771CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002772 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002773 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002774
Steve Naroff88145032009-10-27 14:35:18 +00002775 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002776 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002777}
2778
2779time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002780 if (!SFile)
2781 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002782
Steve Naroff88145032009-10-27 14:35:18 +00002783 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2784 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002785}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002786
Douglas Gregorb9790342010-01-22 21:44:22 +00002787CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2788 if (!tu)
2789 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002790
Ted Kremeneka60ed472010-11-16 08:15:36 +00002791 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002792
Douglas Gregorb9790342010-01-22 21:44:22 +00002793 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002794 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002795}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002796
Ted Kremenekfb480492010-01-13 21:46:36 +00002797} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002798
Ted Kremenekfb480492010-01-13 21:46:36 +00002799//===----------------------------------------------------------------------===//
2800// CXCursor Operations.
2801//===----------------------------------------------------------------------===//
2802
Ted Kremenekfb480492010-01-13 21:46:36 +00002803static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002804 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2805 return getDeclFromExpr(CE->getSubExpr());
2806
Ted Kremenekfb480492010-01-13 21:46:36 +00002807 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2808 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002809 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2810 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002811 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2812 return ME->getMemberDecl();
2813 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2814 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002815 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002816 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002817
Ted Kremenekfb480492010-01-13 21:46:36 +00002818 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2819 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002820 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2821 if (!CE->isElidable())
2822 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002823 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2824 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002825
Douglas Gregordb1314e2010-10-01 21:11:22 +00002826 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2827 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002828 if (SubstNonTypeTemplateParmPackExpr *NTTP
2829 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2830 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002831 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2832 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2833 isa<ParmVarDecl>(SizeOfPack->getPack()))
2834 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002835
Ted Kremenekfb480492010-01-13 21:46:36 +00002836 return 0;
2837}
2838
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002839static SourceLocation getLocationFromExpr(Expr *E) {
2840 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2841 return /*FIXME:*/Msg->getLeftLoc();
2842 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2843 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002844 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2845 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002846 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2847 return Member->getMemberLoc();
2848 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2849 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002850 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2851 return SizeOfPack->getPackLoc();
2852
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002853 return E->getLocStart();
2854}
2855
Ted Kremenekfb480492010-01-13 21:46:36 +00002856extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002857
2858unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002859 CXCursorVisitor visitor,
2860 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002861 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
2862 getCursorASTUnit(parent)->getMaxPCHLevel());
Douglas Gregorb1373d02010-01-20 20:59:29 +00002863 return CursorVis.VisitChildren(parent);
2864}
2865
David Chisnall3387c652010-11-03 14:12:26 +00002866#ifndef __has_feature
2867#define __has_feature(x) 0
2868#endif
2869#if __has_feature(blocks)
2870typedef enum CXChildVisitResult
2871 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2872
2873static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2874 CXClientData client_data) {
2875 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2876 return block(cursor, parent);
2877}
2878#else
2879// If we are compiled with a compiler that doesn't have native blocks support,
2880// define and call the block manually, so the
2881typedef struct _CXChildVisitResult
2882{
2883 void *isa;
2884 int flags;
2885 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002886 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2887 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002888} *CXCursorVisitorBlock;
2889
2890static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2891 CXClientData client_data) {
2892 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2893 return block->invoke(block, cursor, parent);
2894}
2895#endif
2896
2897
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002898unsigned clang_visitChildrenWithBlock(CXCursor parent,
2899 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002900 return clang_visitChildren(parent, visitWithBlock, block);
2901}
2902
Douglas Gregor78205d42010-01-20 21:45:58 +00002903static CXString getDeclSpelling(Decl *D) {
2904 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00002905 if (!ND) {
2906 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2907 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2908 return createCXString(Property->getIdentifier()->getName());
2909
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002910 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00002911 }
2912
Douglas Gregor78205d42010-01-20 21:45:58 +00002913 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002914 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002915
Douglas Gregor78205d42010-01-20 21:45:58 +00002916 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2917 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2918 // and returns different names. NamedDecl returns the class name and
2919 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002920 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002921
Douglas Gregor0a35bce2010-09-01 03:07:18 +00002922 if (isa<UsingDirectiveDecl>(D))
2923 return createCXString("");
2924
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00002925 llvm::SmallString<1024> S;
2926 llvm::raw_svector_ostream os(S);
2927 ND->printName(os);
2928
2929 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00002930}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002931
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002932CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002933 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00002934 return clang_getTranslationUnitSpelling(
2935 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002936
Steve Narofff334b4e2009-09-02 18:26:48 +00002937 if (clang_isReference(C.kind)) {
2938 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00002939 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00002940 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002941 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002942 }
2943 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00002944 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002945 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002946 }
2947 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00002948 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00002949 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002950 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002951 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00002952 case CXCursor_CXXBaseSpecifier: {
2953 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
2954 return createCXString(B->getType().getAsString());
2955 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002956 case CXCursor_TypeRef: {
2957 TypeDecl *Type = getCursorTypeRef(C).first;
2958 assert(Type && "Missing type decl");
2959
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002960 return createCXString(getCursorContext(C).getTypeDeclType(Type).
2961 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002962 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00002963 case CXCursor_TemplateRef: {
2964 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00002965 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00002966
2967 return createCXString(Template->getNameAsString());
2968 }
Douglas Gregor69319002010-08-31 23:48:11 +00002969
2970 case CXCursor_NamespaceRef: {
2971 NamedDecl *NS = getCursorNamespaceRef(C).first;
2972 assert(NS && "Missing namespace decl");
2973
2974 return createCXString(NS->getNameAsString());
2975 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002976
Douglas Gregora67e03f2010-09-09 21:42:20 +00002977 case CXCursor_MemberRef: {
2978 FieldDecl *Field = getCursorMemberRef(C).first;
2979 assert(Field && "Missing member decl");
2980
2981 return createCXString(Field->getNameAsString());
2982 }
2983
Douglas Gregor36897b02010-09-10 00:22:18 +00002984 case CXCursor_LabelRef: {
2985 LabelStmt *Label = getCursorLabelRef(C).first;
2986 assert(Label && "Missing label");
2987
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002988 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00002989 }
2990
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00002991 case CXCursor_OverloadedDeclRef: {
2992 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
2993 if (Decl *D = Storage.dyn_cast<Decl *>()) {
2994 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
2995 return createCXString(ND->getNameAsString());
2996 return createCXString("");
2997 }
2998 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
2999 return createCXString(E->getName().getAsString());
3000 OverloadedTemplateStorage *Ovl
3001 = Storage.get<OverloadedTemplateStorage*>();
3002 if (Ovl->size() == 0)
3003 return createCXString("");
3004 return createCXString((*Ovl->begin())->getNameAsString());
3005 }
3006
Daniel Dunbaracca7252009-11-30 20:42:49 +00003007 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003008 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003009 }
3010 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003011
3012 if (clang_isExpression(C.kind)) {
3013 Decl *D = getDeclFromExpr(getCursorExpr(C));
3014 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003015 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003016 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003017 }
3018
Douglas Gregor36897b02010-09-10 00:22:18 +00003019 if (clang_isStatement(C.kind)) {
3020 Stmt *S = getCursorStmt(C);
3021 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003022 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003023
3024 return createCXString("");
3025 }
3026
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003027 if (C.kind == CXCursor_MacroInstantiation)
3028 return createCXString(getCursorMacroInstantiation(C)->getName()
3029 ->getNameStart());
3030
Douglas Gregor572feb22010-03-18 18:04:21 +00003031 if (C.kind == CXCursor_MacroDefinition)
3032 return createCXString(getCursorMacroDefinition(C)->getName()
3033 ->getNameStart());
3034
Douglas Gregorecdcb882010-10-20 22:00:55 +00003035 if (C.kind == CXCursor_InclusionDirective)
3036 return createCXString(getCursorInclusionDirective(C)->getFileName());
3037
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003038 if (clang_isDeclaration(C.kind))
3039 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003040
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003041 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003042}
3043
Douglas Gregor358559d2010-10-02 22:49:11 +00003044CXString clang_getCursorDisplayName(CXCursor C) {
3045 if (!clang_isDeclaration(C.kind))
3046 return clang_getCursorSpelling(C);
3047
3048 Decl *D = getCursorDecl(C);
3049 if (!D)
3050 return createCXString("");
3051
3052 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3053 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3054 D = FunTmpl->getTemplatedDecl();
3055
3056 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3057 llvm::SmallString<64> Str;
3058 llvm::raw_svector_ostream OS(Str);
3059 OS << Function->getNameAsString();
3060 if (Function->getPrimaryTemplate())
3061 OS << "<>";
3062 OS << "(";
3063 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3064 if (I)
3065 OS << ", ";
3066 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3067 }
3068
3069 if (Function->isVariadic()) {
3070 if (Function->getNumParams())
3071 OS << ", ";
3072 OS << "...";
3073 }
3074 OS << ")";
3075 return createCXString(OS.str());
3076 }
3077
3078 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3079 llvm::SmallString<64> Str;
3080 llvm::raw_svector_ostream OS(Str);
3081 OS << ClassTemplate->getNameAsString();
3082 OS << "<";
3083 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3084 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3085 if (I)
3086 OS << ", ";
3087
3088 NamedDecl *Param = Params->getParam(I);
3089 if (Param->getIdentifier()) {
3090 OS << Param->getIdentifier()->getName();
3091 continue;
3092 }
3093
3094 // There is no parameter name, which makes this tricky. Try to come up
3095 // with something useful that isn't too long.
3096 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3097 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3098 else if (NonTypeTemplateParmDecl *NTTP
3099 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3100 OS << NTTP->getType().getAsString(Policy);
3101 else
3102 OS << "template<...> class";
3103 }
3104
3105 OS << ">";
3106 return createCXString(OS.str());
3107 }
3108
3109 if (ClassTemplateSpecializationDecl *ClassSpec
3110 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3111 // If the type was explicitly written, use that.
3112 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3113 return createCXString(TSInfo->getType().getAsString(Policy));
3114
3115 llvm::SmallString<64> Str;
3116 llvm::raw_svector_ostream OS(Str);
3117 OS << ClassSpec->getNameAsString();
3118 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003119 ClassSpec->getTemplateArgs().data(),
3120 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003121 Policy);
3122 return createCXString(OS.str());
3123 }
3124
3125 return clang_getCursorSpelling(C);
3126}
3127
Ted Kremeneke68fff62010-02-17 00:41:32 +00003128CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003129 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003130 case CXCursor_FunctionDecl:
3131 return createCXString("FunctionDecl");
3132 case CXCursor_TypedefDecl:
3133 return createCXString("TypedefDecl");
3134 case CXCursor_EnumDecl:
3135 return createCXString("EnumDecl");
3136 case CXCursor_EnumConstantDecl:
3137 return createCXString("EnumConstantDecl");
3138 case CXCursor_StructDecl:
3139 return createCXString("StructDecl");
3140 case CXCursor_UnionDecl:
3141 return createCXString("UnionDecl");
3142 case CXCursor_ClassDecl:
3143 return createCXString("ClassDecl");
3144 case CXCursor_FieldDecl:
3145 return createCXString("FieldDecl");
3146 case CXCursor_VarDecl:
3147 return createCXString("VarDecl");
3148 case CXCursor_ParmDecl:
3149 return createCXString("ParmDecl");
3150 case CXCursor_ObjCInterfaceDecl:
3151 return createCXString("ObjCInterfaceDecl");
3152 case CXCursor_ObjCCategoryDecl:
3153 return createCXString("ObjCCategoryDecl");
3154 case CXCursor_ObjCProtocolDecl:
3155 return createCXString("ObjCProtocolDecl");
3156 case CXCursor_ObjCPropertyDecl:
3157 return createCXString("ObjCPropertyDecl");
3158 case CXCursor_ObjCIvarDecl:
3159 return createCXString("ObjCIvarDecl");
3160 case CXCursor_ObjCInstanceMethodDecl:
3161 return createCXString("ObjCInstanceMethodDecl");
3162 case CXCursor_ObjCClassMethodDecl:
3163 return createCXString("ObjCClassMethodDecl");
3164 case CXCursor_ObjCImplementationDecl:
3165 return createCXString("ObjCImplementationDecl");
3166 case CXCursor_ObjCCategoryImplDecl:
3167 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003168 case CXCursor_CXXMethod:
3169 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003170 case CXCursor_UnexposedDecl:
3171 return createCXString("UnexposedDecl");
3172 case CXCursor_ObjCSuperClassRef:
3173 return createCXString("ObjCSuperClassRef");
3174 case CXCursor_ObjCProtocolRef:
3175 return createCXString("ObjCProtocolRef");
3176 case CXCursor_ObjCClassRef:
3177 return createCXString("ObjCClassRef");
3178 case CXCursor_TypeRef:
3179 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003180 case CXCursor_TemplateRef:
3181 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003182 case CXCursor_NamespaceRef:
3183 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003184 case CXCursor_MemberRef:
3185 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003186 case CXCursor_LabelRef:
3187 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003188 case CXCursor_OverloadedDeclRef:
3189 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003190 case CXCursor_UnexposedExpr:
3191 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003192 case CXCursor_BlockExpr:
3193 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003194 case CXCursor_DeclRefExpr:
3195 return createCXString("DeclRefExpr");
3196 case CXCursor_MemberRefExpr:
3197 return createCXString("MemberRefExpr");
3198 case CXCursor_CallExpr:
3199 return createCXString("CallExpr");
3200 case CXCursor_ObjCMessageExpr:
3201 return createCXString("ObjCMessageExpr");
3202 case CXCursor_UnexposedStmt:
3203 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003204 case CXCursor_LabelStmt:
3205 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003206 case CXCursor_InvalidFile:
3207 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003208 case CXCursor_InvalidCode:
3209 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003210 case CXCursor_NoDeclFound:
3211 return createCXString("NoDeclFound");
3212 case CXCursor_NotImplemented:
3213 return createCXString("NotImplemented");
3214 case CXCursor_TranslationUnit:
3215 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003216 case CXCursor_UnexposedAttr:
3217 return createCXString("UnexposedAttr");
3218 case CXCursor_IBActionAttr:
3219 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003220 case CXCursor_IBOutletAttr:
3221 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003222 case CXCursor_IBOutletCollectionAttr:
3223 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003224 case CXCursor_PreprocessingDirective:
3225 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003226 case CXCursor_MacroDefinition:
3227 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003228 case CXCursor_MacroInstantiation:
3229 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003230 case CXCursor_InclusionDirective:
3231 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003232 case CXCursor_Namespace:
3233 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003234 case CXCursor_LinkageSpec:
3235 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003236 case CXCursor_CXXBaseSpecifier:
3237 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003238 case CXCursor_Constructor:
3239 return createCXString("CXXConstructor");
3240 case CXCursor_Destructor:
3241 return createCXString("CXXDestructor");
3242 case CXCursor_ConversionFunction:
3243 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003244 case CXCursor_TemplateTypeParameter:
3245 return createCXString("TemplateTypeParameter");
3246 case CXCursor_NonTypeTemplateParameter:
3247 return createCXString("NonTypeTemplateParameter");
3248 case CXCursor_TemplateTemplateParameter:
3249 return createCXString("TemplateTemplateParameter");
3250 case CXCursor_FunctionTemplate:
3251 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003252 case CXCursor_ClassTemplate:
3253 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003254 case CXCursor_ClassTemplatePartialSpecialization:
3255 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003256 case CXCursor_NamespaceAlias:
3257 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003258 case CXCursor_UsingDirective:
3259 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003260 case CXCursor_UsingDeclaration:
3261 return createCXString("UsingDeclaration");
Steve Naroff89922f82009-08-31 00:59:03 +00003262 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003263
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003264 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003265 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003266}
Steve Naroff89922f82009-08-31 00:59:03 +00003267
Ted Kremeneke68fff62010-02-17 00:41:32 +00003268enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3269 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003270 CXClientData client_data) {
3271 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003272
3273 // If our current best cursor is the construction of a temporary object,
3274 // don't replace that cursor with a type reference, because we want
3275 // clang_getCursor() to point at the constructor.
3276 if (clang_isExpression(BestCursor->kind) &&
3277 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3278 cursor.kind == CXCursor_TypeRef)
3279 return CXChildVisit_Recurse;
3280
Douglas Gregor85fe1562010-12-10 07:23:11 +00003281 // Don't override a preprocessing cursor with another preprocessing
3282 // cursor; we want the outermost preprocessing cursor.
3283 if (clang_isPreprocessing(cursor.kind) &&
3284 clang_isPreprocessing(BestCursor->kind))
3285 return CXChildVisit_Recurse;
3286
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003287 *BestCursor = cursor;
3288 return CXChildVisit_Recurse;
3289}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003290
Douglas Gregorb9790342010-01-22 21:44:22 +00003291CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3292 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003293 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003294
Ted Kremeneka60ed472010-11-16 08:15:36 +00003295 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003296 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3297
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003298 // Translate the given source location to make it point at the beginning of
3299 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003300 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003301
3302 // Guard against an invalid SourceLocation, or we may assert in one
3303 // of the following calls.
3304 if (SLoc.isInvalid())
3305 return clang_getNullCursor();
3306
Douglas Gregor40749ee2010-11-03 00:35:38 +00003307 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003308 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3309 CXXUnit->getASTContext().getLangOptions());
3310
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003311 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3312 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003313 // FIXME: Would be great to have a "hint" cursor, then walk from that
3314 // hint cursor upward until we find a cursor whose source range encloses
3315 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003316 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3317 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003318 Decl::MaxPCHLevel, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003319 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003320 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003321
3322 if (Logging) {
3323 CXFile SearchFile;
3324 unsigned SearchLine, SearchColumn;
3325 CXFile ResultFile;
3326 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003327 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3328 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003329 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3330
3331 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3332 0);
3333 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3334 &ResultColumn, 0);
3335 SearchFileName = clang_getFileName(SearchFile);
3336 ResultFileName = clang_getFileName(ResultFile);
3337 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003338 USR = clang_getCursorUSR(Result);
3339 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003340 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3341 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003342 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3343 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003344 clang_disposeString(SearchFileName);
3345 clang_disposeString(ResultFileName);
3346 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003347 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003348
3349 CXCursor Definition = clang_getCursorDefinition(Result);
3350 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3351 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3352 CXString DefinitionKindSpelling
3353 = clang_getCursorKindSpelling(Definition.kind);
3354 CXFile DefinitionFile;
3355 unsigned DefinitionLine, DefinitionColumn;
3356 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3357 &DefinitionLine, &DefinitionColumn, 0);
3358 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3359 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3360 clang_getCString(DefinitionKindSpelling),
3361 clang_getCString(DefinitionFileName),
3362 DefinitionLine, DefinitionColumn);
3363 clang_disposeString(DefinitionFileName);
3364 clang_disposeString(DefinitionKindSpelling);
3365 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003366 }
3367
Ted Kremeneke68fff62010-02-17 00:41:32 +00003368 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003369}
3370
Ted Kremenek73885552009-11-17 19:28:59 +00003371CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003372 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003373}
3374
3375unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003376 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003377}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003378
Douglas Gregor9ce55842010-11-20 00:09:34 +00003379unsigned clang_hashCursor(CXCursor C) {
3380 unsigned Index = 0;
3381 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3382 Index = 1;
3383
3384 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3385 std::make_pair(C.kind, C.data[Index]));
3386}
3387
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003388unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003389 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3390}
3391
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003392unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003393 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3394}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003395
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003396unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003397 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3398}
3399
Douglas Gregor97b98722010-01-19 23:20:36 +00003400unsigned clang_isExpression(enum CXCursorKind K) {
3401 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3402}
3403
3404unsigned clang_isStatement(enum CXCursorKind K) {
3405 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3406}
3407
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003408unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3409 return K == CXCursor_TranslationUnit;
3410}
3411
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003412unsigned clang_isPreprocessing(enum CXCursorKind K) {
3413 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3414}
3415
Ted Kremenekad6eff62010-03-08 21:17:29 +00003416unsigned clang_isUnexposed(enum CXCursorKind K) {
3417 switch (K) {
3418 case CXCursor_UnexposedDecl:
3419 case CXCursor_UnexposedExpr:
3420 case CXCursor_UnexposedStmt:
3421 case CXCursor_UnexposedAttr:
3422 return true;
3423 default:
3424 return false;
3425 }
3426}
3427
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003428CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003429 return C.kind;
3430}
3431
Douglas Gregor98258af2010-01-18 22:46:11 +00003432CXSourceLocation clang_getCursorLocation(CXCursor C) {
3433 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003434 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003435 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003436 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3437 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003438 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003439 }
3440
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003441 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003442 std::pair<ObjCProtocolDecl *, SourceLocation> P
3443 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003444 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003445 }
3446
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003447 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003448 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3449 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003450 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003451 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003452
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003453 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003454 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003455 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003456 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003457
3458 case CXCursor_TemplateRef: {
3459 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3460 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3461 }
3462
Douglas Gregor69319002010-08-31 23:48:11 +00003463 case CXCursor_NamespaceRef: {
3464 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3465 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3466 }
3467
Douglas Gregora67e03f2010-09-09 21:42:20 +00003468 case CXCursor_MemberRef: {
3469 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3470 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3471 }
3472
Ted Kremenek3064ef92010-08-27 21:34:58 +00003473 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003474 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3475 if (!BaseSpec)
3476 return clang_getNullLocation();
3477
3478 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3479 return cxloc::translateSourceLocation(getCursorContext(C),
3480 TSInfo->getTypeLoc().getBeginLoc());
3481
3482 return cxloc::translateSourceLocation(getCursorContext(C),
3483 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003484 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003485
Douglas Gregor36897b02010-09-10 00:22:18 +00003486 case CXCursor_LabelRef: {
3487 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3488 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3489 }
3490
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003491 case CXCursor_OverloadedDeclRef:
3492 return cxloc::translateSourceLocation(getCursorContext(C),
3493 getCursorOverloadedDeclRef(C).second);
3494
Douglas Gregorf46034a2010-01-18 23:41:10 +00003495 default:
3496 // FIXME: Need a way to enumerate all non-reference cases.
3497 llvm_unreachable("Missed a reference kind");
3498 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003499 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003500
3501 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003502 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003503 getLocationFromExpr(getCursorExpr(C)));
3504
Douglas Gregor36897b02010-09-10 00:22:18 +00003505 if (clang_isStatement(C.kind))
3506 return cxloc::translateSourceLocation(getCursorContext(C),
3507 getCursorStmt(C)->getLocStart());
3508
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003509 if (C.kind == CXCursor_PreprocessingDirective) {
3510 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3511 return cxloc::translateSourceLocation(getCursorContext(C), L);
3512 }
Douglas Gregor48072312010-03-18 15:23:44 +00003513
3514 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003515 SourceLocation L
3516 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003517 return cxloc::translateSourceLocation(getCursorContext(C), L);
3518 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003519
3520 if (C.kind == CXCursor_MacroDefinition) {
3521 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3522 return cxloc::translateSourceLocation(getCursorContext(C), L);
3523 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003524
3525 if (C.kind == CXCursor_InclusionDirective) {
3526 SourceLocation L
3527 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3528 return cxloc::translateSourceLocation(getCursorContext(C), L);
3529 }
3530
Ted Kremenek9a700d22010-05-12 06:16:13 +00003531 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003532 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003533
Douglas Gregorf46034a2010-01-18 23:41:10 +00003534 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003535 SourceLocation Loc = D->getLocation();
3536 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3537 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003538 // FIXME: Multiple variables declared in a single declaration
3539 // currently lack the information needed to correctly determine their
3540 // ranges when accounting for the type-specifier. We use context
3541 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3542 // and if so, whether it is the first decl.
3543 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3544 if (!cxcursor::isFirstInDeclGroup(C))
3545 Loc = VD->getLocation();
3546 }
3547
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003548 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003549}
Douglas Gregora7bde202010-01-19 00:34:46 +00003550
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003551} // end extern "C"
3552
3553static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003554 if (clang_isReference(C.kind)) {
3555 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003556 case CXCursor_ObjCSuperClassRef:
3557 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003558
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003559 case CXCursor_ObjCProtocolRef:
3560 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003561
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003562 case CXCursor_ObjCClassRef:
3563 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003564
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003565 case CXCursor_TypeRef:
3566 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003567
3568 case CXCursor_TemplateRef:
3569 return getCursorTemplateRef(C).second;
3570
Douglas Gregor69319002010-08-31 23:48:11 +00003571 case CXCursor_NamespaceRef:
3572 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003573
3574 case CXCursor_MemberRef:
3575 return getCursorMemberRef(C).second;
3576
Ted Kremenek3064ef92010-08-27 21:34:58 +00003577 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003578 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003579
Douglas Gregor36897b02010-09-10 00:22:18 +00003580 case CXCursor_LabelRef:
3581 return getCursorLabelRef(C).second;
3582
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003583 case CXCursor_OverloadedDeclRef:
3584 return getCursorOverloadedDeclRef(C).second;
3585
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003586 default:
3587 // FIXME: Need a way to enumerate all non-reference cases.
3588 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003589 }
3590 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003591
3592 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003593 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003594
3595 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003596 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003597
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003598 if (C.kind == CXCursor_PreprocessingDirective)
3599 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003600
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003601 if (C.kind == CXCursor_MacroInstantiation)
3602 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003603
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003604 if (C.kind == CXCursor_MacroDefinition)
3605 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003606
3607 if (C.kind == CXCursor_InclusionDirective)
3608 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3609
Ted Kremenek007a7c92010-11-01 23:26:51 +00003610 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3611 Decl *D = cxcursor::getCursorDecl(C);
3612 SourceRange R = D->getSourceRange();
3613 // FIXME: Multiple variables declared in a single declaration
3614 // currently lack the information needed to correctly determine their
3615 // ranges when accounting for the type-specifier. We use context
3616 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3617 // and if so, whether it is the first decl.
3618 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3619 if (!cxcursor::isFirstInDeclGroup(C))
3620 R.setBegin(VD->getLocation());
3621 }
3622 return R;
3623 }
Douglas Gregor66537982010-11-17 17:14:07 +00003624 return SourceRange();
3625}
3626
3627/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3628/// the decl-specifier-seq for declarations.
3629static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3630 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3631 Decl *D = cxcursor::getCursorDecl(C);
3632 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003633
Douglas Gregor2494dd02011-03-01 01:34:45 +00003634 // Adjust the start of the location for declarations preceded by
3635 // declaration specifiers.
3636 SourceLocation StartLoc;
3637 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3638 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3639 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3640 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3641 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3642 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3643 }
3644
3645 if (StartLoc.isValid() && R.getBegin().isValid() &&
3646 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3647 R.setBegin(StartLoc);
3648
3649 // FIXME: Multiple variables declared in a single declaration
3650 // currently lack the information needed to correctly determine their
3651 // ranges when accounting for the type-specifier. We use context
3652 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3653 // and if so, whether it is the first decl.
3654 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3655 if (!cxcursor::isFirstInDeclGroup(C))
3656 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003657 }
3658
3659 return R;
3660 }
3661
3662 return getRawCursorExtent(C);
3663}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003664
3665extern "C" {
3666
3667CXSourceRange clang_getCursorExtent(CXCursor C) {
3668 SourceRange R = getRawCursorExtent(C);
3669 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003670 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003671
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003672 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003673}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003674
3675CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003676 if (clang_isInvalid(C.kind))
3677 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003678
Ted Kremeneka60ed472010-11-16 08:15:36 +00003679 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003680 if (clang_isDeclaration(C.kind)) {
3681 Decl *D = getCursorDecl(C);
3682 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003683 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003684 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003685 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003686 if (ObjCForwardProtocolDecl *Protocols
3687 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003688 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003689 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3690 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3691 return MakeCXCursor(Property, tu);
3692
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003693 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003694 }
3695
Douglas Gregor97b98722010-01-19 23:20:36 +00003696 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003697 Expr *E = getCursorExpr(C);
3698 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003699 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003700 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003701
3702 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003703 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003704
Douglas Gregor97b98722010-01-19 23:20:36 +00003705 return clang_getNullCursor();
3706 }
3707
Douglas Gregor36897b02010-09-10 00:22:18 +00003708 if (clang_isStatement(C.kind)) {
3709 Stmt *S = getCursorStmt(C);
3710 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003711 return MakeCXCursor(Goto->getLabel()->getStmt(), getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003712
3713 return clang_getNullCursor();
3714 }
3715
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003716 if (C.kind == CXCursor_MacroInstantiation) {
3717 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003718 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003719 }
3720
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003721 if (!clang_isReference(C.kind))
3722 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003723
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003724 switch (C.kind) {
3725 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003726 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003727
3728 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003729 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003730
3731 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003732 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003733
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003734 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003735 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003736
3737 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003738 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003739
Douglas Gregor69319002010-08-31 23:48:11 +00003740 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003741 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003742
Douglas Gregora67e03f2010-09-09 21:42:20 +00003743 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003744 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003745
Ted Kremenek3064ef92010-08-27 21:34:58 +00003746 case CXCursor_CXXBaseSpecifier: {
3747 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3748 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003749 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003750 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003751
Douglas Gregor36897b02010-09-10 00:22:18 +00003752 case CXCursor_LabelRef:
3753 // FIXME: We end up faking the "parent" declaration here because we
3754 // don't want to make CXCursor larger.
3755 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003756 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3757 .getTranslationUnitDecl(),
3758 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003759
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003760 case CXCursor_OverloadedDeclRef:
3761 return C;
3762
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003763 default:
3764 // We would prefer to enumerate all non-reference cursor kinds here.
3765 llvm_unreachable("Unhandled reference cursor kind");
3766 break;
3767 }
3768 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003769
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003770 return clang_getNullCursor();
3771}
3772
Douglas Gregorb6998662010-01-19 19:34:47 +00003773CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003774 if (clang_isInvalid(C.kind))
3775 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003776
Ted Kremeneka60ed472010-11-16 08:15:36 +00003777 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003778
Douglas Gregorb6998662010-01-19 19:34:47 +00003779 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003780 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003781 C = clang_getCursorReferenced(C);
3782 WasReference = true;
3783 }
3784
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003785 if (C.kind == CXCursor_MacroInstantiation)
3786 return clang_getCursorReferenced(C);
3787
Douglas Gregorb6998662010-01-19 19:34:47 +00003788 if (!clang_isDeclaration(C.kind))
3789 return clang_getNullCursor();
3790
3791 Decl *D = getCursorDecl(C);
3792 if (!D)
3793 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003794
Douglas Gregorb6998662010-01-19 19:34:47 +00003795 switch (D->getKind()) {
3796 // Declaration kinds that don't really separate the notions of
3797 // declaration and definition.
3798 case Decl::Namespace:
3799 case Decl::Typedef:
3800 case Decl::TemplateTypeParm:
3801 case Decl::EnumConstant:
3802 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003803 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003804 case Decl::ObjCIvar:
3805 case Decl::ObjCAtDefsField:
3806 case Decl::ImplicitParam:
3807 case Decl::ParmVar:
3808 case Decl::NonTypeTemplateParm:
3809 case Decl::TemplateTemplateParm:
3810 case Decl::ObjCCategoryImpl:
3811 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003812 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003813 case Decl::LinkageSpec:
3814 case Decl::ObjCPropertyImpl:
3815 case Decl::FileScopeAsm:
3816 case Decl::StaticAssert:
3817 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003818 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003819 return C;
3820
3821 // Declaration kinds that don't make any sense here, but are
3822 // nonetheless harmless.
3823 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003824 break;
3825
3826 // Declaration kinds for which the definition is not resolvable.
3827 case Decl::UnresolvedUsingTypename:
3828 case Decl::UnresolvedUsingValue:
3829 break;
3830
3831 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003832 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003833 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003834
3835 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003836 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003837
3838 case Decl::Enum:
3839 case Decl::Record:
3840 case Decl::CXXRecord:
3841 case Decl::ClassTemplateSpecialization:
3842 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003843 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003844 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003845 return clang_getNullCursor();
3846
3847 case Decl::Function:
3848 case Decl::CXXMethod:
3849 case Decl::CXXConstructor:
3850 case Decl::CXXDestructor:
3851 case Decl::CXXConversion: {
3852 const FunctionDecl *Def = 0;
3853 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003854 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003855 return clang_getNullCursor();
3856 }
3857
3858 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003859 // Ask the variable if it has a definition.
3860 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003861 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003862 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003863 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003864
Douglas Gregorb6998662010-01-19 19:34:47 +00003865 case Decl::FunctionTemplate: {
3866 const FunctionDecl *Def = 0;
3867 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003868 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003869 return clang_getNullCursor();
3870 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003871
Douglas Gregorb6998662010-01-19 19:34:47 +00003872 case Decl::ClassTemplate: {
3873 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003874 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003875 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003876 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003877 return clang_getNullCursor();
3878 }
3879
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003880 case Decl::Using:
3881 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003882 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003883
3884 case Decl::UsingShadow:
3885 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003886 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003887 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003888
3889 case Decl::ObjCMethod: {
3890 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3891 if (Method->isThisDeclarationADefinition())
3892 return C;
3893
3894 // Dig out the method definition in the associated
3895 // @implementation, if we have it.
3896 // FIXME: The ASTs should make finding the definition easier.
3897 if (ObjCInterfaceDecl *Class
3898 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3899 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3900 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3901 Method->isInstanceMethod()))
3902 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003903 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003904
3905 return clang_getNullCursor();
3906 }
3907
3908 case Decl::ObjCCategory:
3909 if (ObjCCategoryImplDecl *Impl
3910 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003911 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003912 return clang_getNullCursor();
3913
3914 case Decl::ObjCProtocol:
3915 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3916 return C;
3917 return clang_getNullCursor();
3918
3919 case Decl::ObjCInterface:
3920 // There are two notions of a "definition" for an Objective-C
3921 // class: the interface and its implementation. When we resolved a
3922 // reference to an Objective-C class, produce the @interface as
3923 // the definition; when we were provided with the interface,
3924 // produce the @implementation as the definition.
3925 if (WasReference) {
3926 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
3927 return C;
3928 } else if (ObjCImplementationDecl *Impl
3929 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003930 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003931 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003932
Douglas Gregorb6998662010-01-19 19:34:47 +00003933 case Decl::ObjCProperty:
3934 // FIXME: We don't really know where to find the
3935 // ObjCPropertyImplDecls that implement this property.
3936 return clang_getNullCursor();
3937
3938 case Decl::ObjCCompatibleAlias:
3939 if (ObjCInterfaceDecl *Class
3940 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
3941 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003942 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003943
Douglas Gregorb6998662010-01-19 19:34:47 +00003944 return clang_getNullCursor();
3945
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003946 case Decl::ObjCForwardProtocol:
3947 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003948 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003949
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003950 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00003951 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003952 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003953
3954 case Decl::Friend:
3955 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003956 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003957 return clang_getNullCursor();
3958
3959 case Decl::FriendTemplate:
3960 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003961 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003962 return clang_getNullCursor();
3963 }
3964
3965 return clang_getNullCursor();
3966}
3967
3968unsigned clang_isCursorDefinition(CXCursor C) {
3969 if (!clang_isDeclaration(C.kind))
3970 return 0;
3971
3972 return clang_getCursorDefinition(C) == C;
3973}
3974
Douglas Gregor1a9d0502010-11-19 23:44:15 +00003975CXCursor clang_getCanonicalCursor(CXCursor C) {
3976 if (!clang_isDeclaration(C.kind))
3977 return C;
3978
3979 if (Decl *D = getCursorDecl(C))
3980 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
3981
3982 return C;
3983}
3984
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003985unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00003986 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003987 return 0;
3988
3989 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3990 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3991 return E->getNumDecls();
3992
3993 if (OverloadedTemplateStorage *S
3994 = Storage.dyn_cast<OverloadedTemplateStorage*>())
3995 return S->size();
3996
3997 Decl *D = Storage.get<Decl*>();
3998 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00003999 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004000 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4001 return Classes->size();
4002 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4003 return Protocols->protocol_size();
4004
4005 return 0;
4006}
4007
4008CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004009 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004010 return clang_getNullCursor();
4011
4012 if (index >= clang_getNumOverloadedDecls(cursor))
4013 return clang_getNullCursor();
4014
Ted Kremeneka60ed472010-11-16 08:15:36 +00004015 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004016 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4017 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004018 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004019
4020 if (OverloadedTemplateStorage *S
4021 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004022 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004023
4024 Decl *D = Storage.get<Decl*>();
4025 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4026 // FIXME: This is, unfortunately, linear time.
4027 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4028 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004029 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004030 }
4031
4032 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004033 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004034
4035 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004036 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004037
4038 return clang_getNullCursor();
4039}
4040
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004041void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004042 const char **startBuf,
4043 const char **endBuf,
4044 unsigned *startLine,
4045 unsigned *startColumn,
4046 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004047 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004048 assert(getCursorDecl(C) && "CXCursor has null decl");
4049 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004050 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4051 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004052
Steve Naroff4ade6d62009-09-23 17:52:52 +00004053 SourceManager &SM = FD->getASTContext().getSourceManager();
4054 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4055 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4056 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4057 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4058 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4059 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4060}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004061
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004062void clang_enableStackTraces(void) {
4063 llvm::sys::PrintStackTraceOnErrorSignal();
4064}
4065
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004066void clang_executeOnThread(void (*fn)(void*), void *user_data,
4067 unsigned stack_size) {
4068 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4069}
4070
Ted Kremenekfb480492010-01-13 21:46:36 +00004071} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004072
Ted Kremenekfb480492010-01-13 21:46:36 +00004073//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004074// Token-based Operations.
4075//===----------------------------------------------------------------------===//
4076
4077/* CXToken layout:
4078 * int_data[0]: a CXTokenKind
4079 * int_data[1]: starting token location
4080 * int_data[2]: token length
4081 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004082 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004083 * otherwise unused.
4084 */
4085extern "C" {
4086
4087CXTokenKind clang_getTokenKind(CXToken CXTok) {
4088 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4089}
4090
4091CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4092 switch (clang_getTokenKind(CXTok)) {
4093 case CXToken_Identifier:
4094 case CXToken_Keyword:
4095 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004096 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4097 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004098
4099 case CXToken_Literal: {
4100 // We have stashed the starting pointer in the ptr_data field. Use it.
4101 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004102 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004103 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004104
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004105 case CXToken_Punctuation:
4106 case CXToken_Comment:
4107 break;
4108 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004109
4110 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004111 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004112 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004113 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004114 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004115
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004116 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4117 std::pair<FileID, unsigned> LocInfo
4118 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004119 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004120 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004121 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4122 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004123 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004124
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004125 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004126}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004127
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004128CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004129 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004130 if (!CXXUnit)
4131 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004132
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004133 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4134 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4135}
4136
4137CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004138 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004139 if (!CXXUnit)
4140 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004141
4142 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004143 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4144}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004145
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004146void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4147 CXToken **Tokens, unsigned *NumTokens) {
4148 if (Tokens)
4149 *Tokens = 0;
4150 if (NumTokens)
4151 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004152
Ted Kremeneka60ed472010-11-16 08:15:36 +00004153 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004154 if (!CXXUnit || !Tokens || !NumTokens)
4155 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004156
Douglas Gregorbdf60622010-03-05 21:16:25 +00004157 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4158
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004159 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004160 if (R.isInvalid())
4161 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004162
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004163 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4164 std::pair<FileID, unsigned> BeginLocInfo
4165 = SourceMgr.getDecomposedLoc(R.getBegin());
4166 std::pair<FileID, unsigned> EndLocInfo
4167 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004168
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004169 // Cannot tokenize across files.
4170 if (BeginLocInfo.first != EndLocInfo.first)
4171 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004172
4173 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004174 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004175 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004176 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004177 if (Invalid)
4178 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004179
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004180 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4181 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004182 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004183 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004184
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004185 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004186 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004187 llvm::SmallVector<CXToken, 32> CXTokens;
4188 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004189 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004190 do {
4191 // Lex the next token
4192 Lex.LexFromRawLexer(Tok);
4193 if (Tok.is(tok::eof))
4194 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004195
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004196 // Initialize the CXToken.
4197 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004198
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004199 // - Common fields
4200 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4201 CXTok.int_data[2] = Tok.getLength();
4202 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004203
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004204 // - Kind-specific fields
4205 if (Tok.isLiteral()) {
4206 CXTok.int_data[0] = CXToken_Literal;
4207 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004208 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004209 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004210 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004211 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004212
David Chisnall096428b2010-10-13 21:44:48 +00004213 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004214 CXTok.int_data[0] = CXToken_Keyword;
4215 }
4216 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004217 CXTok.int_data[0] = Tok.is(tok::identifier)
4218 ? CXToken_Identifier
4219 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004220 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004221 CXTok.ptr_data = II;
4222 } else if (Tok.is(tok::comment)) {
4223 CXTok.int_data[0] = CXToken_Comment;
4224 CXTok.ptr_data = 0;
4225 } else {
4226 CXTok.int_data[0] = CXToken_Punctuation;
4227 CXTok.ptr_data = 0;
4228 }
4229 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004230 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004231 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004232
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004233 if (CXTokens.empty())
4234 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004235
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004236 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4237 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4238 *NumTokens = CXTokens.size();
4239}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004240
Ted Kremenek6db61092010-05-05 00:55:15 +00004241void clang_disposeTokens(CXTranslationUnit TU,
4242 CXToken *Tokens, unsigned NumTokens) {
4243 free(Tokens);
4244}
4245
4246} // end: extern "C"
4247
4248//===----------------------------------------------------------------------===//
4249// Token annotation APIs.
4250//===----------------------------------------------------------------------===//
4251
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004252typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004253static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4254 CXCursor parent,
4255 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004256namespace {
4257class AnnotateTokensWorker {
4258 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004259 CXToken *Tokens;
4260 CXCursor *Cursors;
4261 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004262 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004263 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004264 CursorVisitor AnnotateVis;
4265 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004266 bool HasContextSensitiveKeywords;
4267
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004268 bool MoreTokens() const { return TokIdx < NumTokens; }
4269 unsigned NextToken() const { return TokIdx; }
4270 void AdvanceToken() { ++TokIdx; }
4271 SourceLocation GetTokenLoc(unsigned tokI) {
4272 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4273 }
4274
Ted Kremenek6db61092010-05-05 00:55:15 +00004275public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004276 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004277 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004278 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004279 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004280 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004281 AnnotateVis(tu,
4282 AnnotateTokensVisitor, this,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004283 Decl::MaxPCHLevel, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004284 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4285 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004286
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004287 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004288 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004289 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004290 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004291 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004292 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004293
4294 /// \brief Determine whether the annotator saw any cursors that have
4295 /// context-sensitive keywords.
4296 bool hasContextSensitiveKeywords() const {
4297 return HasContextSensitiveKeywords;
4298 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004299};
4300}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004301
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004302void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4303 // Walk the AST within the region of interest, annotating tokens
4304 // along the way.
4305 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004306
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004307 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4308 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004309 if (Pos != Annotated.end() &&
4310 (clang_isInvalid(Cursors[I].kind) ||
4311 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004312 Cursors[I] = Pos->second;
4313 }
4314
4315 // Finish up annotating any tokens left.
4316 if (!MoreTokens())
4317 return;
4318
4319 const CXCursor &C = clang_getNullCursor();
4320 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4321 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4322 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004323 }
4324}
4325
Ted Kremenek6db61092010-05-05 00:55:15 +00004326enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004327AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004328 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004329 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004330 if (cursorRange.isInvalid())
4331 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004332
4333 if (!HasContextSensitiveKeywords) {
4334 // Objective-C properties can have context-sensitive keywords.
4335 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4336 if (ObjCPropertyDecl *Property
4337 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4338 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4339 }
4340 // Objective-C methods can have context-sensitive keywords.
4341 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4342 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4343 if (ObjCMethodDecl *Method
4344 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4345 if (Method->getObjCDeclQualifier())
4346 HasContextSensitiveKeywords = true;
4347 else {
4348 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4349 PEnd = Method->param_end();
4350 P != PEnd; ++P) {
4351 if ((*P)->getObjCDeclQualifier()) {
4352 HasContextSensitiveKeywords = true;
4353 break;
4354 }
4355 }
4356 }
4357 }
4358 }
4359 // C++ methods can have context-sensitive keywords.
4360 else if (cursor.kind == CXCursor_CXXMethod) {
4361 if (CXXMethodDecl *Method
4362 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4363 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4364 HasContextSensitiveKeywords = true;
4365 }
4366 }
4367 // C++ classes can have context-sensitive keywords.
4368 else if (cursor.kind == CXCursor_StructDecl ||
4369 cursor.kind == CXCursor_ClassDecl ||
4370 cursor.kind == CXCursor_ClassTemplate ||
4371 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4372 if (Decl *D = getCursorDecl(cursor))
4373 if (D->hasAttr<FinalAttr>())
4374 HasContextSensitiveKeywords = true;
4375 }
4376 }
4377
Douglas Gregor4419b672010-10-21 06:10:04 +00004378 if (clang_isPreprocessing(cursor.kind)) {
4379 // For macro instantiations, just note where the beginning of the macro
4380 // instantiation occurs.
4381 if (cursor.kind == CXCursor_MacroInstantiation) {
4382 Annotated[Loc.int_data] = cursor;
4383 return CXChildVisit_Recurse;
4384 }
4385
Douglas Gregor4419b672010-10-21 06:10:04 +00004386 // Items in the preprocessing record are kept separate from items in
4387 // declarations, so we keep a separate token index.
4388 unsigned SavedTokIdx = TokIdx;
4389 TokIdx = PreprocessingTokIdx;
4390
4391 // Skip tokens up until we catch up to the beginning of the preprocessing
4392 // entry.
4393 while (MoreTokens()) {
4394 const unsigned I = NextToken();
4395 SourceLocation TokLoc = GetTokenLoc(I);
4396 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4397 case RangeBefore:
4398 AdvanceToken();
4399 continue;
4400 case RangeAfter:
4401 case RangeOverlap:
4402 break;
4403 }
4404 break;
4405 }
4406
4407 // Look at all of the tokens within this range.
4408 while (MoreTokens()) {
4409 const unsigned I = NextToken();
4410 SourceLocation TokLoc = GetTokenLoc(I);
4411 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4412 case RangeBefore:
4413 assert(0 && "Infeasible");
4414 case RangeAfter:
4415 break;
4416 case RangeOverlap:
4417 Cursors[I] = cursor;
4418 AdvanceToken();
4419 continue;
4420 }
4421 break;
4422 }
4423
4424 // Save the preprocessing token index; restore the non-preprocessing
4425 // token index.
4426 PreprocessingTokIdx = TokIdx;
4427 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004428 return CXChildVisit_Recurse;
4429 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004430
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004431 if (cursorRange.isInvalid())
4432 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004433
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004434 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4435
Ted Kremeneka333c662010-05-12 05:29:33 +00004436 // Adjust the annotated range based specific declarations.
4437 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4438 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004439 Decl *D = cxcursor::getCursorDecl(cursor);
4440 // Don't visit synthesized ObjC methods, since they have no syntatic
4441 // representation in the source.
4442 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4443 if (MD->isSynthesized())
4444 return CXChildVisit_Continue;
4445 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004446
4447 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004448 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004449 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4450 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4451 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4452 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4453 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004454 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004455
4456 if (StartLoc.isValid() && L.isValid() &&
4457 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4458 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004459 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004460
Ted Kremenek3f404602010-08-14 01:14:06 +00004461 // If the location of the cursor occurs within a macro instantiation, record
4462 // the spelling location of the cursor in our annotation map. We can then
4463 // paper over the token labelings during a post-processing step to try and
4464 // get cursor mappings for tokens that are the *arguments* of a macro
4465 // instantiation.
4466 if (L.isMacroID()) {
4467 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4468 // Only invalidate the old annotation if it isn't part of a preprocessing
4469 // directive. Here we assume that the default construction of CXCursor
4470 // results in CXCursor.kind being an initialized value (i.e., 0). If
4471 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004472
Ted Kremenek3f404602010-08-14 01:14:06 +00004473 CXCursor &oldC = Annotated[rawEncoding];
4474 if (!clang_isPreprocessing(oldC.kind))
4475 oldC = cursor;
4476 }
4477
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004478 const enum CXCursorKind K = clang_getCursorKind(parent);
4479 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004480 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4481 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004482
4483 while (MoreTokens()) {
4484 const unsigned I = NextToken();
4485 SourceLocation TokLoc = GetTokenLoc(I);
4486 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4487 case RangeBefore:
4488 Cursors[I] = updateC;
4489 AdvanceToken();
4490 continue;
4491 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004492 case RangeOverlap:
4493 break;
4494 }
4495 break;
4496 }
4497
4498 // Visit children to get their cursor information.
4499 const unsigned BeforeChildren = NextToken();
4500 VisitChildren(cursor);
4501 const unsigned AfterChildren = NextToken();
4502
4503 // Adjust 'Last' to the last token within the extent of the cursor.
4504 while (MoreTokens()) {
4505 const unsigned I = NextToken();
4506 SourceLocation TokLoc = GetTokenLoc(I);
4507 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4508 case RangeBefore:
4509 assert(0 && "Infeasible");
4510 case RangeAfter:
4511 break;
4512 case RangeOverlap:
4513 Cursors[I] = updateC;
4514 AdvanceToken();
4515 continue;
4516 }
4517 break;
4518 }
4519 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004520
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004521 // Scan the tokens that are at the beginning of the cursor, but are not
4522 // capture by the child cursors.
4523
4524 // For AST elements within macros, rely on a post-annotate pass to
4525 // to correctly annotate the tokens with cursors. Otherwise we can
4526 // get confusing results of having tokens that map to cursors that really
4527 // are expanded by an instantiation.
4528 if (L.isMacroID())
4529 cursor = clang_getNullCursor();
4530
4531 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4532 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4533 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004534
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004535 Cursors[I] = cursor;
4536 }
4537 // Scan the tokens that are at the end of the cursor, but are not captured
4538 // but the child cursors.
4539 for (unsigned I = AfterChildren; I != Last; ++I)
4540 Cursors[I] = cursor;
4541
4542 TokIdx = Last;
4543 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004544}
4545
Ted Kremenek6db61092010-05-05 00:55:15 +00004546static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4547 CXCursor parent,
4548 CXClientData client_data) {
4549 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4550}
4551
Ted Kremenekab979612010-11-11 08:05:23 +00004552// This gets run a separate thread to avoid stack blowout.
4553static void runAnnotateTokensWorker(void *UserData) {
4554 ((AnnotateTokensWorker*)UserData)->AnnotateTokens();
4555}
4556
Ted Kremenek6db61092010-05-05 00:55:15 +00004557extern "C" {
4558
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004559void clang_annotateTokens(CXTranslationUnit TU,
4560 CXToken *Tokens, unsigned NumTokens,
4561 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004562
4563 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004564 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004565
Douglas Gregor4419b672010-10-21 06:10:04 +00004566 // Any token we don't specifically annotate will have a NULL cursor.
4567 CXCursor C = clang_getNullCursor();
4568 for (unsigned I = 0; I != NumTokens; ++I)
4569 Cursors[I] = C;
4570
Ted Kremeneka60ed472010-11-16 08:15:36 +00004571 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004572 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004573 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004574
Douglas Gregorbdf60622010-03-05 21:16:25 +00004575 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004576
Douglas Gregor0396f462010-03-19 05:22:59 +00004577 // Determine the region of interest, which contains all of the tokens.
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004578 SourceRange RegionOfInterest;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004579 RegionOfInterest.setBegin(cxloc::translateSourceLocation(
4580 clang_getTokenLocation(TU, Tokens[0])));
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00004581 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
4582 clang_getTokenLocation(TU,
4583 Tokens[NumTokens - 1])));
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004584
Douglas Gregor0396f462010-03-19 05:22:59 +00004585 // A mapping from the source locations found when re-lexing or traversing the
4586 // region of interest to the corresponding cursors.
4587 AnnotateTokensData Annotated;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004588
4589 // Relex the tokens within the source range to look for preprocessing
Douglas Gregor0396f462010-03-19 05:22:59 +00004590 // directives.
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004591 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4592 std::pair<FileID, unsigned> BeginLocInfo
4593 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4594 std::pair<FileID, unsigned> EndLocInfo
4595 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004596
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004597 llvm::StringRef Buffer;
Douglas Gregor0396f462010-03-19 05:22:59 +00004598 bool Invalid = false;
4599 if (BeginLocInfo.first == EndLocInfo.first &&
4600 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4601 !Invalid) {
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004602 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4603 CXXUnit->getASTContext().getLangOptions(),
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004604 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
Douglas Gregor4ae8f292010-03-18 17:52:52 +00004605 Buffer.end());
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004606 Lex.SetCommentRetentionState(true);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004607
4608 // Lex tokens in raw mode until we hit the end of the range, to avoid
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004609 // entering #includes or expanding macros.
Douglas Gregor48072312010-03-18 15:23:44 +00004610 while (true) {
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004611 Token Tok;
4612 Lex.LexFromRawLexer(Tok);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004613
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004614 reprocess:
4615 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4616 // We have found a preprocessing directive. Gobble it up so that we
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004617 // don't see it while preprocessing these tokens later, but keep track
4618 // of all of the token locations inside this preprocessing directive so
4619 // that we can annotate them appropriately.
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004620 //
4621 // FIXME: Some simple tests here could identify macro definitions and
4622 // #undefs, to provide specific cursor kinds for those.
4623 std::vector<SourceLocation> Locations;
4624 do {
4625 Locations.push_back(Tok.getLocation());
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004626 Lex.LexFromRawLexer(Tok);
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004627 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004628
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004629 using namespace cxcursor;
4630 CXCursor Cursor
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004631 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4632 Locations.back()),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004633 TU);
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004634 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4635 Annotated[Locations[I].getRawEncoding()] = Cursor;
4636 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004637
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004638 if (Tok.isAtStartOfLine())
4639 goto reprocess;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004640
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004641 continue;
4642 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004643
Douglas Gregor48072312010-03-18 15:23:44 +00004644 if (Tok.is(tok::eof))
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004645 break;
4646 }
Douglas Gregor4ae8f292010-03-18 17:52:52 +00004647 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004648
Douglas Gregor0396f462010-03-19 05:22:59 +00004649 // Annotate all of the source locations in the region of interest that map to
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004650 // a specific cursor.
4651 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004652 TU, RegionOfInterest);
Ted Kremenekab979612010-11-11 08:05:23 +00004653
4654 // Run the worker within a CrashRecoveryContext.
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004655 // FIXME: We use a ridiculous stack size here because the data-recursion
4656 // algorithm uses a large stack frame than the non-data recursive version,
4657 // and AnnotationTokensWorker currently transforms the data-recursion
4658 // algorithm back into a traditional recursion by explicitly calling
4659 // VisitChildren(). We will need to remove this explicit recursive call.
Ted Kremenekab979612010-11-11 08:05:23 +00004660 llvm::CrashRecoveryContext CRC;
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004661 if (!RunSafely(CRC, runAnnotateTokensWorker, &W,
4662 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004663 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4664 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004665
4666 // If we ran into any entities that involve context-sensitive keywords,
4667 // take another pass through the tokens to mark them as such.
4668 if (W.hasContextSensitiveKeywords()) {
4669 for (unsigned I = 0; I != NumTokens; ++I) {
4670 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4671 continue;
4672
4673 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4674 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4675 if (ObjCPropertyDecl *Property
4676 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4677 if (Property->getPropertyAttributesAsWritten() != 0 &&
4678 llvm::StringSwitch<bool>(II->getName())
4679 .Case("readonly", true)
4680 .Case("assign", true)
4681 .Case("readwrite", true)
4682 .Case("retain", true)
4683 .Case("copy", true)
4684 .Case("nonatomic", true)
4685 .Case("atomic", true)
4686 .Case("getter", true)
4687 .Case("setter", true)
4688 .Default(false))
4689 Tokens[I].int_data[0] = CXToken_Keyword;
4690 }
4691 continue;
4692 }
4693
4694 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4695 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4696 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4697 if (llvm::StringSwitch<bool>(II->getName())
4698 .Case("in", true)
4699 .Case("out", true)
4700 .Case("inout", true)
4701 .Case("oneway", true)
4702 .Case("bycopy", true)
4703 .Case("byref", true)
4704 .Default(false))
4705 Tokens[I].int_data[0] = CXToken_Keyword;
4706 continue;
4707 }
4708
4709 if (Cursors[I].kind == CXCursor_CXXMethod) {
4710 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4711 if (CXXMethodDecl *Method
4712 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4713 if ((Method->hasAttr<FinalAttr>() ||
4714 Method->hasAttr<OverrideAttr>()) &&
4715 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4716 llvm::StringSwitch<bool>(II->getName())
4717 .Case("final", true)
4718 .Case("override", true)
4719 .Default(false))
4720 Tokens[I].int_data[0] = CXToken_Keyword;
4721 }
4722 continue;
4723 }
4724
4725 if (Cursors[I].kind == CXCursor_ClassDecl ||
4726 Cursors[I].kind == CXCursor_StructDecl ||
4727 Cursors[I].kind == CXCursor_ClassTemplate) {
4728 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4729 if (II->getName() == "final") {
4730 // We have to be careful with 'final', since it could be the name
4731 // of a member class rather than the context-sensitive keyword.
4732 // So, check whether the cursor associated with this
4733 Decl *D = getCursorDecl(Cursors[I]);
4734 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4735 if ((Record->hasAttr<FinalAttr>()) &&
4736 Record->getIdentifier() != II)
4737 Tokens[I].int_data[0] = CXToken_Keyword;
4738 } else if (ClassTemplateDecl *ClassTemplate
4739 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4740 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4741 if ((Record->hasAttr<FinalAttr>()) &&
4742 Record->getIdentifier() != II)
4743 Tokens[I].int_data[0] = CXToken_Keyword;
4744 }
4745 }
4746 continue;
4747 }
4748 }
4749 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004750}
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004751} // end: extern "C"
4752
4753//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004754// Operations for querying linkage of a cursor.
4755//===----------------------------------------------------------------------===//
4756
4757extern "C" {
4758CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004759 if (!clang_isDeclaration(cursor.kind))
4760 return CXLinkage_Invalid;
4761
Ted Kremenek16b42592010-03-03 06:36:57 +00004762 Decl *D = cxcursor::getCursorDecl(cursor);
4763 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4764 switch (ND->getLinkage()) {
4765 case NoLinkage: return CXLinkage_NoLinkage;
4766 case InternalLinkage: return CXLinkage_Internal;
4767 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4768 case ExternalLinkage: return CXLinkage_External;
4769 };
4770
4771 return CXLinkage_Invalid;
4772}
4773} // end: extern "C"
4774
4775//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004776// Operations for querying language of a cursor.
4777//===----------------------------------------------------------------------===//
4778
4779static CXLanguageKind getDeclLanguage(const Decl *D) {
4780 switch (D->getKind()) {
4781 default:
4782 break;
4783 case Decl::ImplicitParam:
4784 case Decl::ObjCAtDefsField:
4785 case Decl::ObjCCategory:
4786 case Decl::ObjCCategoryImpl:
4787 case Decl::ObjCClass:
4788 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004789 case Decl::ObjCForwardProtocol:
4790 case Decl::ObjCImplementation:
4791 case Decl::ObjCInterface:
4792 case Decl::ObjCIvar:
4793 case Decl::ObjCMethod:
4794 case Decl::ObjCProperty:
4795 case Decl::ObjCPropertyImpl:
4796 case Decl::ObjCProtocol:
4797 return CXLanguage_ObjC;
4798 case Decl::CXXConstructor:
4799 case Decl::CXXConversion:
4800 case Decl::CXXDestructor:
4801 case Decl::CXXMethod:
4802 case Decl::CXXRecord:
4803 case Decl::ClassTemplate:
4804 case Decl::ClassTemplatePartialSpecialization:
4805 case Decl::ClassTemplateSpecialization:
4806 case Decl::Friend:
4807 case Decl::FriendTemplate:
4808 case Decl::FunctionTemplate:
4809 case Decl::LinkageSpec:
4810 case Decl::Namespace:
4811 case Decl::NamespaceAlias:
4812 case Decl::NonTypeTemplateParm:
4813 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004814 case Decl::TemplateTemplateParm:
4815 case Decl::TemplateTypeParm:
4816 case Decl::UnresolvedUsingTypename:
4817 case Decl::UnresolvedUsingValue:
4818 case Decl::Using:
4819 case Decl::UsingDirective:
4820 case Decl::UsingShadow:
4821 return CXLanguage_CPlusPlus;
4822 }
4823
4824 return CXLanguage_C;
4825}
4826
4827extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004828
4829enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4830 if (clang_isDeclaration(cursor.kind))
4831 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
4832 if (D->hasAttr<UnavailableAttr>() ||
4833 (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()))
4834 return CXAvailability_Available;
4835
4836 if (D->hasAttr<DeprecatedAttr>())
4837 return CXAvailability_Deprecated;
4838 }
4839
4840 return CXAvailability_Available;
4841}
4842
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004843CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4844 if (clang_isDeclaration(cursor.kind))
4845 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4846
4847 return CXLanguage_Invalid;
4848}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004849
4850 /// \brief If the given cursor is the "templated" declaration
4851 /// descibing a class or function template, return the class or
4852 /// function template.
4853static Decl *maybeGetTemplateCursor(Decl *D) {
4854 if (!D)
4855 return 0;
4856
4857 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4858 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4859 return FunTmpl;
4860
4861 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4862 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4863 return ClassTmpl;
4864
4865 return D;
4866}
4867
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004868CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4869 if (clang_isDeclaration(cursor.kind)) {
4870 if (Decl *D = getCursorDecl(cursor)) {
4871 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004872 if (!DC)
4873 return clang_getNullCursor();
4874
4875 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4876 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004877 }
4878 }
4879
4880 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4881 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004882 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004883 }
4884
4885 return clang_getNullCursor();
4886}
4887
4888CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4889 if (clang_isDeclaration(cursor.kind)) {
4890 if (Decl *D = getCursorDecl(cursor)) {
4891 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004892 if (!DC)
4893 return clang_getNullCursor();
4894
4895 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4896 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004897 }
4898 }
4899
4900 // FIXME: Note that we can't easily compute the lexical context of a
4901 // statement or expression, so we return nothing.
4902 return clang_getNullCursor();
4903}
4904
Douglas Gregor9f592342010-10-01 20:25:15 +00004905static void CollectOverriddenMethods(DeclContext *Ctx,
4906 ObjCMethodDecl *Method,
4907 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
4908 if (!Ctx)
4909 return;
4910
4911 // If we have a class or category implementation, jump straight to the
4912 // interface.
4913 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
4914 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
4915
4916 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
4917 if (!Container)
4918 return;
4919
4920 // Check whether we have a matching method at this level.
4921 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
4922 Method->isInstanceMethod()))
4923 if (Method != Overridden) {
4924 // We found an override at this level; there is no need to look
4925 // into other protocols or categories.
4926 Methods.push_back(Overridden);
4927 return;
4928 }
4929
4930 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4931 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
4932 PEnd = Protocol->protocol_end();
4933 P != PEnd; ++P)
4934 CollectOverriddenMethods(*P, Method, Methods);
4935 }
4936
4937 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4938 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
4939 PEnd = Category->protocol_end();
4940 P != PEnd; ++P)
4941 CollectOverriddenMethods(*P, Method, Methods);
4942 }
4943
4944 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
4945 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
4946 PEnd = Interface->protocol_end();
4947 P != PEnd; ++P)
4948 CollectOverriddenMethods(*P, Method, Methods);
4949
4950 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
4951 Category; Category = Category->getNextClassCategory())
4952 CollectOverriddenMethods(Category, Method, Methods);
4953
4954 // We only look into the superclass if we haven't found anything yet.
4955 if (Methods.empty())
4956 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
4957 return CollectOverriddenMethods(Super, Method, Methods);
4958 }
4959}
4960
4961void clang_getOverriddenCursors(CXCursor cursor,
4962 CXCursor **overridden,
4963 unsigned *num_overridden) {
4964 if (overridden)
4965 *overridden = 0;
4966 if (num_overridden)
4967 *num_overridden = 0;
4968 if (!overridden || !num_overridden)
4969 return;
4970
4971 if (!clang_isDeclaration(cursor.kind))
4972 return;
4973
4974 Decl *D = getCursorDecl(cursor);
4975 if (!D)
4976 return;
4977
4978 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004979 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00004980 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
4981 *num_overridden = CXXMethod->size_overridden_methods();
4982 if (!*num_overridden)
4983 return;
4984
4985 *overridden = new CXCursor [*num_overridden];
4986 unsigned I = 0;
4987 for (CXXMethodDecl::method_iterator
4988 M = CXXMethod->begin_overridden_methods(),
4989 MEnd = CXXMethod->end_overridden_methods();
4990 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00004991 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00004992 return;
4993 }
4994
4995 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
4996 if (!Method)
4997 return;
4998
4999 // Handle Objective-C methods.
5000 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5001 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5002
5003 if (Methods.empty())
5004 return;
5005
5006 *num_overridden = Methods.size();
5007 *overridden = new CXCursor [Methods.size()];
5008 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005009 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005010}
5011
5012void clang_disposeOverriddenCursors(CXCursor *overridden) {
5013 delete [] overridden;
5014}
5015
Douglas Gregorecdcb882010-10-20 22:00:55 +00005016CXFile clang_getIncludedFile(CXCursor cursor) {
5017 if (cursor.kind != CXCursor_InclusionDirective)
5018 return 0;
5019
5020 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5021 return (void *)ID->getFile();
5022}
5023
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005024} // end: extern "C"
5025
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005026
5027//===----------------------------------------------------------------------===//
5028// C++ AST instrospection.
5029//===----------------------------------------------------------------------===//
5030
5031extern "C" {
5032unsigned clang_CXXMethod_isStatic(CXCursor C) {
5033 if (!clang_isDeclaration(C.kind))
5034 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005035
5036 CXXMethodDecl *Method = 0;
5037 Decl *D = cxcursor::getCursorDecl(C);
5038 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5039 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5040 else
5041 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5042 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005043}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005044
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005045} // end: extern "C"
5046
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005047//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005048// Attribute introspection.
5049//===----------------------------------------------------------------------===//
5050
5051extern "C" {
5052CXType clang_getIBOutletCollectionType(CXCursor C) {
5053 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005054 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005055
5056 IBOutletCollectionAttr *A =
5057 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5058
Douglas Gregor841b2382011-03-06 18:55:32 +00005059 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005060}
5061} // end: extern "C"
5062
5063//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005064// Misc. utility functions.
5065//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005066
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005067/// Default to using an 8 MB stack size on "safety" threads.
5068static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005069
5070namespace clang {
5071
5072bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005073 void (*Fn)(void*), void *UserData,
5074 unsigned Size) {
5075 if (!Size)
5076 Size = GetSafetyThreadStackSize();
5077 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005078 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5079 return CRC.RunSafely(Fn, UserData);
5080}
5081
5082unsigned GetSafetyThreadStackSize() {
5083 return SafetyStackThreadSize;
5084}
5085
5086void SetSafetyThreadStackSize(unsigned Value) {
5087 SafetyStackThreadSize = Value;
5088}
5089
5090}
5091
Ted Kremenek04bb7162010-01-22 22:44:15 +00005092extern "C" {
5093
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005094CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005095 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005096}
5097
5098} // end: extern "C"