blob: c7af7555d2392a09d31d7962ddc6dbee31cae3c2 [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(),
Douglas Gregorb10daed2010-10-11 16:52:23 +00002427 PrecompilePreamble,
2428 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002429 CacheCodeCompetionResults,
2430 CXXPrecompilePreamble,
2431 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002432
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002433 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002434 // Make sure to check that 'Unit' is non-NULL.
2435 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2436 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2437 DEnd = Unit->stored_diag_end();
2438 D != DEnd; ++D) {
2439 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2440 CXString Msg = clang_formatDiagnostic(&Diag,
2441 clang_defaultDiagnosticDisplayOptions());
2442 fprintf(stderr, "%s\n", clang_getCString(Msg));
2443 clang_disposeString(Msg);
2444 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002445#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002446 // On Windows, force a flush, since there may be multiple copies of
2447 // stderr and stdout in the file system, all with different buffers
2448 // but writing to the same device.
2449 fflush(stderr);
2450#endif
2451 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002452 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002453
Ted Kremeneka60ed472010-11-16 08:15:36 +00002454 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002455}
2456CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2457 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002458 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002459 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002460 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002461 unsigned num_unsaved_files,
2462 unsigned options) {
2463 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002464 num_command_line_args, unsaved_files,
2465 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002466 llvm::CrashRecoveryContext CRC;
2467
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002468 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002469 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2470 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2471 fprintf(stderr, " 'command_line_args' : [");
2472 for (int i = 0; i != num_command_line_args; ++i) {
2473 if (i)
2474 fprintf(stderr, ", ");
2475 fprintf(stderr, "'%s'", command_line_args[i]);
2476 }
2477 fprintf(stderr, "],\n");
2478 fprintf(stderr, " 'unsaved_files' : [");
2479 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2480 if (i)
2481 fprintf(stderr, ", ");
2482 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2483 unsaved_files[i].Length);
2484 }
2485 fprintf(stderr, "],\n");
2486 fprintf(stderr, " 'options' : %d,\n", options);
2487 fprintf(stderr, "}\n");
2488
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002489 return 0;
2490 }
2491
2492 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002493}
2494
Douglas Gregor19998442010-08-13 15:35:05 +00002495unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2496 return CXSaveTranslationUnit_None;
2497}
2498
2499int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2500 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002501 if (!TU)
2502 return 1;
2503
Ted Kremeneka60ed472010-11-16 08:15:36 +00002504 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002505}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002506
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002507void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002508 if (CTUnit) {
2509 // If the translation unit has been marked as unsafe to free, just discard
2510 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002511 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002512 return;
2513
Ted Kremeneka60ed472010-11-16 08:15:36 +00002514 delete static_cast<ASTUnit *>(CTUnit->TUData);
2515 disposeCXStringPool(CTUnit->StringPool);
2516 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002517 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002518}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002519
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002520unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2521 return CXReparse_None;
2522}
2523
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002524struct ReparseTranslationUnitInfo {
2525 CXTranslationUnit TU;
2526 unsigned num_unsaved_files;
2527 struct CXUnsavedFile *unsaved_files;
2528 unsigned options;
2529 int result;
2530};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002531
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002532static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002533 ReparseTranslationUnitInfo *RTUI =
2534 static_cast<ReparseTranslationUnitInfo*>(UserData);
2535 CXTranslationUnit TU = RTUI->TU;
2536 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2537 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2538 unsigned options = RTUI->options;
2539 (void) options;
2540 RTUI->result = 1;
2541
Douglas Gregorabc563f2010-07-19 21:46:24 +00002542 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002543 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002544
Ted Kremeneka60ed472010-11-16 08:15:36 +00002545 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002546 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002547
2548 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2549 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2550 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2551 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002552 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002553 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2554 Buffer));
2555 }
2556
Douglas Gregor593b0c12010-09-23 18:47:53 +00002557 if (!CXXUnit->Reparse(RemappedFiles.data(), RemappedFiles.size()))
2558 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002559}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002560
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002561int clang_reparseTranslationUnit(CXTranslationUnit TU,
2562 unsigned num_unsaved_files,
2563 struct CXUnsavedFile *unsaved_files,
2564 unsigned options) {
2565 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2566 options, 0 };
2567 llvm::CrashRecoveryContext CRC;
2568
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002569 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002570 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002571 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002572 return 1;
2573 }
2574
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002575
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002576 return RTUI.result;
2577}
2578
Douglas Gregordf95a132010-08-09 20:45:32 +00002579
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002580CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002581 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002582 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002583
Ted Kremeneka60ed472010-11-16 08:15:36 +00002584 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002585 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002586}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002587
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002588CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002589 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002590 return Result;
2591}
2592
Ted Kremenekfb480492010-01-13 21:46:36 +00002593} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002594
Ted Kremenekfb480492010-01-13 21:46:36 +00002595//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002596// CXSourceLocation and CXSourceRange Operations.
2597//===----------------------------------------------------------------------===//
2598
Douglas Gregorb9790342010-01-22 21:44:22 +00002599extern "C" {
2600CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002601 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002602 return Result;
2603}
2604
2605unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002606 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2607 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2608 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002609}
2610
2611CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2612 CXFile file,
2613 unsigned line,
2614 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002615 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002616 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002617
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002618 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002619 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002620 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002621 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002622 = CXXUnit->getSourceManager().getLocation(File, line, column);
2623 if (SLoc.isInvalid()) {
2624 if (Logging)
2625 llvm::errs() << "clang_getLocation(\"" << File->getName()
2626 << "\", " << line << ", " << column << ") = invalid\n";
2627 return clang_getNullLocation();
2628 }
2629
2630 if (Logging)
2631 llvm::errs() << "clang_getLocation(\"" << File->getName()
2632 << "\", " << line << ", " << column << ") = "
2633 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002634
2635 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2636}
2637
2638CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2639 CXFile file,
2640 unsigned offset) {
2641 if (!tu || !file)
2642 return clang_getNullLocation();
2643
Ted Kremeneka60ed472010-11-16 08:15:36 +00002644 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002645 SourceLocation Start
2646 = CXXUnit->getSourceManager().getLocation(
2647 static_cast<const FileEntry *>(file),
2648 1, 1);
2649 if (Start.isInvalid()) return clang_getNullLocation();
2650
2651 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2652
2653 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002654
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002655 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002656}
2657
Douglas Gregor5352ac02010-01-28 00:27:43 +00002658CXSourceRange clang_getNullRange() {
2659 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2660 return Result;
2661}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002662
Douglas Gregor5352ac02010-01-28 00:27:43 +00002663CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2664 if (begin.ptr_data[0] != end.ptr_data[0] ||
2665 begin.ptr_data[1] != end.ptr_data[1])
2666 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002667
2668 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002669 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002670 return Result;
2671}
2672
Douglas Gregor46766dc2010-01-26 19:19:08 +00002673void clang_getInstantiationLocation(CXSourceLocation location,
2674 CXFile *file,
2675 unsigned *line,
2676 unsigned *column,
2677 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002678 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2679
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002680 if (!location.ptr_data[0] || Loc.isInvalid()) {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002681 if (file)
2682 *file = 0;
2683 if (line)
2684 *line = 0;
2685 if (column)
2686 *column = 0;
2687 if (offset)
2688 *offset = 0;
2689 return;
2690 }
2691
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002692 const SourceManager &SM =
2693 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002694 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002695
2696 if (file)
2697 *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));
2698 if (line)
2699 *line = SM.getInstantiationLineNumber(InstLoc);
2700 if (column)
2701 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002702 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002703 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002704}
2705
Douglas Gregora9b06d42010-11-09 06:24:54 +00002706void clang_getSpellingLocation(CXSourceLocation location,
2707 CXFile *file,
2708 unsigned *line,
2709 unsigned *column,
2710 unsigned *offset) {
2711 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2712
2713 if (!location.ptr_data[0] || Loc.isInvalid()) {
2714 if (file)
2715 *file = 0;
2716 if (line)
2717 *line = 0;
2718 if (column)
2719 *column = 0;
2720 if (offset)
2721 *offset = 0;
2722 return;
2723 }
2724
2725 const SourceManager &SM =
2726 *static_cast<const SourceManager*>(location.ptr_data[0]);
2727 SourceLocation SpellLoc = Loc;
2728 if (SpellLoc.isMacroID()) {
2729 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2730 if (SimpleSpellingLoc.isFileID() &&
2731 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2732 SpellLoc = SimpleSpellingLoc;
2733 else
2734 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2735 }
2736
2737 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2738 FileID FID = LocInfo.first;
2739 unsigned FileOffset = LocInfo.second;
2740
2741 if (file)
2742 *file = (void *)SM.getFileEntryForID(FID);
2743 if (line)
2744 *line = SM.getLineNumber(FID, FileOffset);
2745 if (column)
2746 *column = SM.getColumnNumber(FID, FileOffset);
2747 if (offset)
2748 *offset = FileOffset;
2749}
2750
Douglas Gregor1db19de2010-01-19 21:36:55 +00002751CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002752 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002753 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002754 return Result;
2755}
2756
2757CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002758 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002759 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002760 return Result;
2761}
2762
Douglas Gregorb9790342010-01-22 21:44:22 +00002763} // end: extern "C"
2764
Douglas Gregor1db19de2010-01-19 21:36:55 +00002765//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002766// CXFile Operations.
2767//===----------------------------------------------------------------------===//
2768
2769extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002770CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002771 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002772 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002773
Steve Naroff88145032009-10-27 14:35:18 +00002774 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002775 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002776}
2777
2778time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002779 if (!SFile)
2780 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002781
Steve Naroff88145032009-10-27 14:35:18 +00002782 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2783 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002784}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002785
Douglas Gregorb9790342010-01-22 21:44:22 +00002786CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2787 if (!tu)
2788 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002789
Ted Kremeneka60ed472010-11-16 08:15:36 +00002790 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002791
Douglas Gregorb9790342010-01-22 21:44:22 +00002792 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002793 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002794}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002795
Ted Kremenekfb480492010-01-13 21:46:36 +00002796} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002797
Ted Kremenekfb480492010-01-13 21:46:36 +00002798//===----------------------------------------------------------------------===//
2799// CXCursor Operations.
2800//===----------------------------------------------------------------------===//
2801
Ted Kremenekfb480492010-01-13 21:46:36 +00002802static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002803 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2804 return getDeclFromExpr(CE->getSubExpr());
2805
Ted Kremenekfb480492010-01-13 21:46:36 +00002806 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2807 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002808 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2809 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002810 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2811 return ME->getMemberDecl();
2812 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2813 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002814 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002815 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002816
Ted Kremenekfb480492010-01-13 21:46:36 +00002817 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2818 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002819 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2820 if (!CE->isElidable())
2821 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002822 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2823 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002824
Douglas Gregordb1314e2010-10-01 21:11:22 +00002825 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2826 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002827 if (SubstNonTypeTemplateParmPackExpr *NTTP
2828 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2829 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002830 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2831 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2832 isa<ParmVarDecl>(SizeOfPack->getPack()))
2833 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002834
Ted Kremenekfb480492010-01-13 21:46:36 +00002835 return 0;
2836}
2837
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002838static SourceLocation getLocationFromExpr(Expr *E) {
2839 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2840 return /*FIXME:*/Msg->getLeftLoc();
2841 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2842 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002843 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2844 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002845 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2846 return Member->getMemberLoc();
2847 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2848 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002849 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2850 return SizeOfPack->getPackLoc();
2851
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002852 return E->getLocStart();
2853}
2854
Ted Kremenekfb480492010-01-13 21:46:36 +00002855extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002856
2857unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002858 CXCursorVisitor visitor,
2859 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002860 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
2861 getCursorASTUnit(parent)->getMaxPCHLevel());
Douglas Gregorb1373d02010-01-20 20:59:29 +00002862 return CursorVis.VisitChildren(parent);
2863}
2864
David Chisnall3387c652010-11-03 14:12:26 +00002865#ifndef __has_feature
2866#define __has_feature(x) 0
2867#endif
2868#if __has_feature(blocks)
2869typedef enum CXChildVisitResult
2870 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2871
2872static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2873 CXClientData client_data) {
2874 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2875 return block(cursor, parent);
2876}
2877#else
2878// If we are compiled with a compiler that doesn't have native blocks support,
2879// define and call the block manually, so the
2880typedef struct _CXChildVisitResult
2881{
2882 void *isa;
2883 int flags;
2884 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002885 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2886 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002887} *CXCursorVisitorBlock;
2888
2889static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2890 CXClientData client_data) {
2891 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2892 return block->invoke(block, cursor, parent);
2893}
2894#endif
2895
2896
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002897unsigned clang_visitChildrenWithBlock(CXCursor parent,
2898 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002899 return clang_visitChildren(parent, visitWithBlock, block);
2900}
2901
Douglas Gregor78205d42010-01-20 21:45:58 +00002902static CXString getDeclSpelling(Decl *D) {
2903 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00002904 if (!ND) {
2905 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2906 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2907 return createCXString(Property->getIdentifier()->getName());
2908
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002909 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00002910 }
2911
Douglas Gregor78205d42010-01-20 21:45:58 +00002912 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002913 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002914
Douglas Gregor78205d42010-01-20 21:45:58 +00002915 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2916 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2917 // and returns different names. NamedDecl returns the class name and
2918 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002919 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002920
Douglas Gregor0a35bce2010-09-01 03:07:18 +00002921 if (isa<UsingDirectiveDecl>(D))
2922 return createCXString("");
2923
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00002924 llvm::SmallString<1024> S;
2925 llvm::raw_svector_ostream os(S);
2926 ND->printName(os);
2927
2928 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00002929}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002930
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002931CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002932 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00002933 return clang_getTranslationUnitSpelling(
2934 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002935
Steve Narofff334b4e2009-09-02 18:26:48 +00002936 if (clang_isReference(C.kind)) {
2937 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00002938 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00002939 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002940 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002941 }
2942 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00002943 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002944 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002945 }
2946 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00002947 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00002948 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002949 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002950 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00002951 case CXCursor_CXXBaseSpecifier: {
2952 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
2953 return createCXString(B->getType().getAsString());
2954 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002955 case CXCursor_TypeRef: {
2956 TypeDecl *Type = getCursorTypeRef(C).first;
2957 assert(Type && "Missing type decl");
2958
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002959 return createCXString(getCursorContext(C).getTypeDeclType(Type).
2960 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002961 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00002962 case CXCursor_TemplateRef: {
2963 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00002964 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00002965
2966 return createCXString(Template->getNameAsString());
2967 }
Douglas Gregor69319002010-08-31 23:48:11 +00002968
2969 case CXCursor_NamespaceRef: {
2970 NamedDecl *NS = getCursorNamespaceRef(C).first;
2971 assert(NS && "Missing namespace decl");
2972
2973 return createCXString(NS->getNameAsString());
2974 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002975
Douglas Gregora67e03f2010-09-09 21:42:20 +00002976 case CXCursor_MemberRef: {
2977 FieldDecl *Field = getCursorMemberRef(C).first;
2978 assert(Field && "Missing member decl");
2979
2980 return createCXString(Field->getNameAsString());
2981 }
2982
Douglas Gregor36897b02010-09-10 00:22:18 +00002983 case CXCursor_LabelRef: {
2984 LabelStmt *Label = getCursorLabelRef(C).first;
2985 assert(Label && "Missing label");
2986
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002987 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00002988 }
2989
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00002990 case CXCursor_OverloadedDeclRef: {
2991 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
2992 if (Decl *D = Storage.dyn_cast<Decl *>()) {
2993 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
2994 return createCXString(ND->getNameAsString());
2995 return createCXString("");
2996 }
2997 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
2998 return createCXString(E->getName().getAsString());
2999 OverloadedTemplateStorage *Ovl
3000 = Storage.get<OverloadedTemplateStorage*>();
3001 if (Ovl->size() == 0)
3002 return createCXString("");
3003 return createCXString((*Ovl->begin())->getNameAsString());
3004 }
3005
Daniel Dunbaracca7252009-11-30 20:42:49 +00003006 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003007 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003008 }
3009 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003010
3011 if (clang_isExpression(C.kind)) {
3012 Decl *D = getDeclFromExpr(getCursorExpr(C));
3013 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003014 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003015 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003016 }
3017
Douglas Gregor36897b02010-09-10 00:22:18 +00003018 if (clang_isStatement(C.kind)) {
3019 Stmt *S = getCursorStmt(C);
3020 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003021 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003022
3023 return createCXString("");
3024 }
3025
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003026 if (C.kind == CXCursor_MacroInstantiation)
3027 return createCXString(getCursorMacroInstantiation(C)->getName()
3028 ->getNameStart());
3029
Douglas Gregor572feb22010-03-18 18:04:21 +00003030 if (C.kind == CXCursor_MacroDefinition)
3031 return createCXString(getCursorMacroDefinition(C)->getName()
3032 ->getNameStart());
3033
Douglas Gregorecdcb882010-10-20 22:00:55 +00003034 if (C.kind == CXCursor_InclusionDirective)
3035 return createCXString(getCursorInclusionDirective(C)->getFileName());
3036
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003037 if (clang_isDeclaration(C.kind))
3038 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003039
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003040 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003041}
3042
Douglas Gregor358559d2010-10-02 22:49:11 +00003043CXString clang_getCursorDisplayName(CXCursor C) {
3044 if (!clang_isDeclaration(C.kind))
3045 return clang_getCursorSpelling(C);
3046
3047 Decl *D = getCursorDecl(C);
3048 if (!D)
3049 return createCXString("");
3050
3051 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3052 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3053 D = FunTmpl->getTemplatedDecl();
3054
3055 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3056 llvm::SmallString<64> Str;
3057 llvm::raw_svector_ostream OS(Str);
3058 OS << Function->getNameAsString();
3059 if (Function->getPrimaryTemplate())
3060 OS << "<>";
3061 OS << "(";
3062 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3063 if (I)
3064 OS << ", ";
3065 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3066 }
3067
3068 if (Function->isVariadic()) {
3069 if (Function->getNumParams())
3070 OS << ", ";
3071 OS << "...";
3072 }
3073 OS << ")";
3074 return createCXString(OS.str());
3075 }
3076
3077 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3078 llvm::SmallString<64> Str;
3079 llvm::raw_svector_ostream OS(Str);
3080 OS << ClassTemplate->getNameAsString();
3081 OS << "<";
3082 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3083 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3084 if (I)
3085 OS << ", ";
3086
3087 NamedDecl *Param = Params->getParam(I);
3088 if (Param->getIdentifier()) {
3089 OS << Param->getIdentifier()->getName();
3090 continue;
3091 }
3092
3093 // There is no parameter name, which makes this tricky. Try to come up
3094 // with something useful that isn't too long.
3095 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3096 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3097 else if (NonTypeTemplateParmDecl *NTTP
3098 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3099 OS << NTTP->getType().getAsString(Policy);
3100 else
3101 OS << "template<...> class";
3102 }
3103
3104 OS << ">";
3105 return createCXString(OS.str());
3106 }
3107
3108 if (ClassTemplateSpecializationDecl *ClassSpec
3109 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3110 // If the type was explicitly written, use that.
3111 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3112 return createCXString(TSInfo->getType().getAsString(Policy));
3113
3114 llvm::SmallString<64> Str;
3115 llvm::raw_svector_ostream OS(Str);
3116 OS << ClassSpec->getNameAsString();
3117 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003118 ClassSpec->getTemplateArgs().data(),
3119 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003120 Policy);
3121 return createCXString(OS.str());
3122 }
3123
3124 return clang_getCursorSpelling(C);
3125}
3126
Ted Kremeneke68fff62010-02-17 00:41:32 +00003127CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003128 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003129 case CXCursor_FunctionDecl:
3130 return createCXString("FunctionDecl");
3131 case CXCursor_TypedefDecl:
3132 return createCXString("TypedefDecl");
3133 case CXCursor_EnumDecl:
3134 return createCXString("EnumDecl");
3135 case CXCursor_EnumConstantDecl:
3136 return createCXString("EnumConstantDecl");
3137 case CXCursor_StructDecl:
3138 return createCXString("StructDecl");
3139 case CXCursor_UnionDecl:
3140 return createCXString("UnionDecl");
3141 case CXCursor_ClassDecl:
3142 return createCXString("ClassDecl");
3143 case CXCursor_FieldDecl:
3144 return createCXString("FieldDecl");
3145 case CXCursor_VarDecl:
3146 return createCXString("VarDecl");
3147 case CXCursor_ParmDecl:
3148 return createCXString("ParmDecl");
3149 case CXCursor_ObjCInterfaceDecl:
3150 return createCXString("ObjCInterfaceDecl");
3151 case CXCursor_ObjCCategoryDecl:
3152 return createCXString("ObjCCategoryDecl");
3153 case CXCursor_ObjCProtocolDecl:
3154 return createCXString("ObjCProtocolDecl");
3155 case CXCursor_ObjCPropertyDecl:
3156 return createCXString("ObjCPropertyDecl");
3157 case CXCursor_ObjCIvarDecl:
3158 return createCXString("ObjCIvarDecl");
3159 case CXCursor_ObjCInstanceMethodDecl:
3160 return createCXString("ObjCInstanceMethodDecl");
3161 case CXCursor_ObjCClassMethodDecl:
3162 return createCXString("ObjCClassMethodDecl");
3163 case CXCursor_ObjCImplementationDecl:
3164 return createCXString("ObjCImplementationDecl");
3165 case CXCursor_ObjCCategoryImplDecl:
3166 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003167 case CXCursor_CXXMethod:
3168 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003169 case CXCursor_UnexposedDecl:
3170 return createCXString("UnexposedDecl");
3171 case CXCursor_ObjCSuperClassRef:
3172 return createCXString("ObjCSuperClassRef");
3173 case CXCursor_ObjCProtocolRef:
3174 return createCXString("ObjCProtocolRef");
3175 case CXCursor_ObjCClassRef:
3176 return createCXString("ObjCClassRef");
3177 case CXCursor_TypeRef:
3178 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003179 case CXCursor_TemplateRef:
3180 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003181 case CXCursor_NamespaceRef:
3182 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003183 case CXCursor_MemberRef:
3184 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003185 case CXCursor_LabelRef:
3186 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003187 case CXCursor_OverloadedDeclRef:
3188 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003189 case CXCursor_UnexposedExpr:
3190 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003191 case CXCursor_BlockExpr:
3192 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003193 case CXCursor_DeclRefExpr:
3194 return createCXString("DeclRefExpr");
3195 case CXCursor_MemberRefExpr:
3196 return createCXString("MemberRefExpr");
3197 case CXCursor_CallExpr:
3198 return createCXString("CallExpr");
3199 case CXCursor_ObjCMessageExpr:
3200 return createCXString("ObjCMessageExpr");
3201 case CXCursor_UnexposedStmt:
3202 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003203 case CXCursor_LabelStmt:
3204 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003205 case CXCursor_InvalidFile:
3206 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003207 case CXCursor_InvalidCode:
3208 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003209 case CXCursor_NoDeclFound:
3210 return createCXString("NoDeclFound");
3211 case CXCursor_NotImplemented:
3212 return createCXString("NotImplemented");
3213 case CXCursor_TranslationUnit:
3214 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003215 case CXCursor_UnexposedAttr:
3216 return createCXString("UnexposedAttr");
3217 case CXCursor_IBActionAttr:
3218 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003219 case CXCursor_IBOutletAttr:
3220 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003221 case CXCursor_IBOutletCollectionAttr:
3222 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003223 case CXCursor_PreprocessingDirective:
3224 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003225 case CXCursor_MacroDefinition:
3226 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003227 case CXCursor_MacroInstantiation:
3228 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003229 case CXCursor_InclusionDirective:
3230 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003231 case CXCursor_Namespace:
3232 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003233 case CXCursor_LinkageSpec:
3234 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003235 case CXCursor_CXXBaseSpecifier:
3236 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003237 case CXCursor_Constructor:
3238 return createCXString("CXXConstructor");
3239 case CXCursor_Destructor:
3240 return createCXString("CXXDestructor");
3241 case CXCursor_ConversionFunction:
3242 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003243 case CXCursor_TemplateTypeParameter:
3244 return createCXString("TemplateTypeParameter");
3245 case CXCursor_NonTypeTemplateParameter:
3246 return createCXString("NonTypeTemplateParameter");
3247 case CXCursor_TemplateTemplateParameter:
3248 return createCXString("TemplateTemplateParameter");
3249 case CXCursor_FunctionTemplate:
3250 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003251 case CXCursor_ClassTemplate:
3252 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003253 case CXCursor_ClassTemplatePartialSpecialization:
3254 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003255 case CXCursor_NamespaceAlias:
3256 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003257 case CXCursor_UsingDirective:
3258 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003259 case CXCursor_UsingDeclaration:
3260 return createCXString("UsingDeclaration");
Steve Naroff89922f82009-08-31 00:59:03 +00003261 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003262
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003263 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003264 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003265}
Steve Naroff89922f82009-08-31 00:59:03 +00003266
Ted Kremeneke68fff62010-02-17 00:41:32 +00003267enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3268 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003269 CXClientData client_data) {
3270 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003271
3272 // If our current best cursor is the construction of a temporary object,
3273 // don't replace that cursor with a type reference, because we want
3274 // clang_getCursor() to point at the constructor.
3275 if (clang_isExpression(BestCursor->kind) &&
3276 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3277 cursor.kind == CXCursor_TypeRef)
3278 return CXChildVisit_Recurse;
3279
Douglas Gregor85fe1562010-12-10 07:23:11 +00003280 // Don't override a preprocessing cursor with another preprocessing
3281 // cursor; we want the outermost preprocessing cursor.
3282 if (clang_isPreprocessing(cursor.kind) &&
3283 clang_isPreprocessing(BestCursor->kind))
3284 return CXChildVisit_Recurse;
3285
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003286 *BestCursor = cursor;
3287 return CXChildVisit_Recurse;
3288}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003289
Douglas Gregorb9790342010-01-22 21:44:22 +00003290CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3291 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003292 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003293
Ted Kremeneka60ed472010-11-16 08:15:36 +00003294 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003295 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3296
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003297 // Translate the given source location to make it point at the beginning of
3298 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003299 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003300
3301 // Guard against an invalid SourceLocation, or we may assert in one
3302 // of the following calls.
3303 if (SLoc.isInvalid())
3304 return clang_getNullCursor();
3305
Douglas Gregor40749ee2010-11-03 00:35:38 +00003306 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003307 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3308 CXXUnit->getASTContext().getLangOptions());
3309
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003310 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3311 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003312 // FIXME: Would be great to have a "hint" cursor, then walk from that
3313 // hint cursor upward until we find a cursor whose source range encloses
3314 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003315 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3316 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003317 Decl::MaxPCHLevel, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003318 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003319 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003320
3321 if (Logging) {
3322 CXFile SearchFile;
3323 unsigned SearchLine, SearchColumn;
3324 CXFile ResultFile;
3325 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003326 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3327 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003328 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3329
3330 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3331 0);
3332 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3333 &ResultColumn, 0);
3334 SearchFileName = clang_getFileName(SearchFile);
3335 ResultFileName = clang_getFileName(ResultFile);
3336 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003337 USR = clang_getCursorUSR(Result);
3338 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003339 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3340 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003341 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3342 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003343 clang_disposeString(SearchFileName);
3344 clang_disposeString(ResultFileName);
3345 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003346 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003347
3348 CXCursor Definition = clang_getCursorDefinition(Result);
3349 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3350 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3351 CXString DefinitionKindSpelling
3352 = clang_getCursorKindSpelling(Definition.kind);
3353 CXFile DefinitionFile;
3354 unsigned DefinitionLine, DefinitionColumn;
3355 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3356 &DefinitionLine, &DefinitionColumn, 0);
3357 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3358 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3359 clang_getCString(DefinitionKindSpelling),
3360 clang_getCString(DefinitionFileName),
3361 DefinitionLine, DefinitionColumn);
3362 clang_disposeString(DefinitionFileName);
3363 clang_disposeString(DefinitionKindSpelling);
3364 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003365 }
3366
Ted Kremeneke68fff62010-02-17 00:41:32 +00003367 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003368}
3369
Ted Kremenek73885552009-11-17 19:28:59 +00003370CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003371 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003372}
3373
3374unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003375 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003376}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003377
Douglas Gregor9ce55842010-11-20 00:09:34 +00003378unsigned clang_hashCursor(CXCursor C) {
3379 unsigned Index = 0;
3380 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3381 Index = 1;
3382
3383 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3384 std::make_pair(C.kind, C.data[Index]));
3385}
3386
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003387unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003388 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3389}
3390
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003391unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003392 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3393}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003394
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003395unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003396 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3397}
3398
Douglas Gregor97b98722010-01-19 23:20:36 +00003399unsigned clang_isExpression(enum CXCursorKind K) {
3400 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3401}
3402
3403unsigned clang_isStatement(enum CXCursorKind K) {
3404 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3405}
3406
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003407unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3408 return K == CXCursor_TranslationUnit;
3409}
3410
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003411unsigned clang_isPreprocessing(enum CXCursorKind K) {
3412 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3413}
3414
Ted Kremenekad6eff62010-03-08 21:17:29 +00003415unsigned clang_isUnexposed(enum CXCursorKind K) {
3416 switch (K) {
3417 case CXCursor_UnexposedDecl:
3418 case CXCursor_UnexposedExpr:
3419 case CXCursor_UnexposedStmt:
3420 case CXCursor_UnexposedAttr:
3421 return true;
3422 default:
3423 return false;
3424 }
3425}
3426
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003427CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003428 return C.kind;
3429}
3430
Douglas Gregor98258af2010-01-18 22:46:11 +00003431CXSourceLocation clang_getCursorLocation(CXCursor C) {
3432 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003433 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003434 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003435 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3436 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003437 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003438 }
3439
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003440 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003441 std::pair<ObjCProtocolDecl *, SourceLocation> P
3442 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003443 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003444 }
3445
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003446 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003447 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3448 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003449 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003450 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003451
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003452 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003453 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003454 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003455 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003456
3457 case CXCursor_TemplateRef: {
3458 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3459 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3460 }
3461
Douglas Gregor69319002010-08-31 23:48:11 +00003462 case CXCursor_NamespaceRef: {
3463 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3464 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3465 }
3466
Douglas Gregora67e03f2010-09-09 21:42:20 +00003467 case CXCursor_MemberRef: {
3468 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3469 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3470 }
3471
Ted Kremenek3064ef92010-08-27 21:34:58 +00003472 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003473 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3474 if (!BaseSpec)
3475 return clang_getNullLocation();
3476
3477 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3478 return cxloc::translateSourceLocation(getCursorContext(C),
3479 TSInfo->getTypeLoc().getBeginLoc());
3480
3481 return cxloc::translateSourceLocation(getCursorContext(C),
3482 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003483 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003484
Douglas Gregor36897b02010-09-10 00:22:18 +00003485 case CXCursor_LabelRef: {
3486 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3487 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3488 }
3489
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003490 case CXCursor_OverloadedDeclRef:
3491 return cxloc::translateSourceLocation(getCursorContext(C),
3492 getCursorOverloadedDeclRef(C).second);
3493
Douglas Gregorf46034a2010-01-18 23:41:10 +00003494 default:
3495 // FIXME: Need a way to enumerate all non-reference cases.
3496 llvm_unreachable("Missed a reference kind");
3497 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003498 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003499
3500 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003501 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003502 getLocationFromExpr(getCursorExpr(C)));
3503
Douglas Gregor36897b02010-09-10 00:22:18 +00003504 if (clang_isStatement(C.kind))
3505 return cxloc::translateSourceLocation(getCursorContext(C),
3506 getCursorStmt(C)->getLocStart());
3507
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003508 if (C.kind == CXCursor_PreprocessingDirective) {
3509 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3510 return cxloc::translateSourceLocation(getCursorContext(C), L);
3511 }
Douglas Gregor48072312010-03-18 15:23:44 +00003512
3513 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003514 SourceLocation L
3515 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003516 return cxloc::translateSourceLocation(getCursorContext(C), L);
3517 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003518
3519 if (C.kind == CXCursor_MacroDefinition) {
3520 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3521 return cxloc::translateSourceLocation(getCursorContext(C), L);
3522 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003523
3524 if (C.kind == CXCursor_InclusionDirective) {
3525 SourceLocation L
3526 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3527 return cxloc::translateSourceLocation(getCursorContext(C), L);
3528 }
3529
Ted Kremenek9a700d22010-05-12 06:16:13 +00003530 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003531 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003532
Douglas Gregorf46034a2010-01-18 23:41:10 +00003533 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003534 SourceLocation Loc = D->getLocation();
3535 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3536 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003537 // FIXME: Multiple variables declared in a single declaration
3538 // currently lack the information needed to correctly determine their
3539 // ranges when accounting for the type-specifier. We use context
3540 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3541 // and if so, whether it is the first decl.
3542 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3543 if (!cxcursor::isFirstInDeclGroup(C))
3544 Loc = VD->getLocation();
3545 }
3546
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003547 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003548}
Douglas Gregora7bde202010-01-19 00:34:46 +00003549
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003550} // end extern "C"
3551
3552static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003553 if (clang_isReference(C.kind)) {
3554 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003555 case CXCursor_ObjCSuperClassRef:
3556 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003557
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003558 case CXCursor_ObjCProtocolRef:
3559 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003560
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003561 case CXCursor_ObjCClassRef:
3562 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003563
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003564 case CXCursor_TypeRef:
3565 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003566
3567 case CXCursor_TemplateRef:
3568 return getCursorTemplateRef(C).second;
3569
Douglas Gregor69319002010-08-31 23:48:11 +00003570 case CXCursor_NamespaceRef:
3571 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003572
3573 case CXCursor_MemberRef:
3574 return getCursorMemberRef(C).second;
3575
Ted Kremenek3064ef92010-08-27 21:34:58 +00003576 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003577 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003578
Douglas Gregor36897b02010-09-10 00:22:18 +00003579 case CXCursor_LabelRef:
3580 return getCursorLabelRef(C).second;
3581
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003582 case CXCursor_OverloadedDeclRef:
3583 return getCursorOverloadedDeclRef(C).second;
3584
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003585 default:
3586 // FIXME: Need a way to enumerate all non-reference cases.
3587 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003588 }
3589 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003590
3591 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003592 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003593
3594 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003595 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003596
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003597 if (C.kind == CXCursor_PreprocessingDirective)
3598 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003599
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003600 if (C.kind == CXCursor_MacroInstantiation)
3601 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003602
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003603 if (C.kind == CXCursor_MacroDefinition)
3604 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003605
3606 if (C.kind == CXCursor_InclusionDirective)
3607 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3608
Ted Kremenek007a7c92010-11-01 23:26:51 +00003609 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3610 Decl *D = cxcursor::getCursorDecl(C);
3611 SourceRange R = D->getSourceRange();
3612 // FIXME: Multiple variables declared in a single declaration
3613 // currently lack the information needed to correctly determine their
3614 // ranges when accounting for the type-specifier. We use context
3615 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3616 // and if so, whether it is the first decl.
3617 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3618 if (!cxcursor::isFirstInDeclGroup(C))
3619 R.setBegin(VD->getLocation());
3620 }
3621 return R;
3622 }
Douglas Gregor66537982010-11-17 17:14:07 +00003623 return SourceRange();
3624}
3625
3626/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3627/// the decl-specifier-seq for declarations.
3628static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3629 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3630 Decl *D = cxcursor::getCursorDecl(C);
3631 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003632
Douglas Gregor2494dd02011-03-01 01:34:45 +00003633 // Adjust the start of the location for declarations preceded by
3634 // declaration specifiers.
3635 SourceLocation StartLoc;
3636 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3637 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3638 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3639 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3640 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3641 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3642 }
3643
3644 if (StartLoc.isValid() && R.getBegin().isValid() &&
3645 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3646 R.setBegin(StartLoc);
3647
3648 // FIXME: Multiple variables declared in a single declaration
3649 // currently lack the information needed to correctly determine their
3650 // ranges when accounting for the type-specifier. We use context
3651 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3652 // and if so, whether it is the first decl.
3653 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3654 if (!cxcursor::isFirstInDeclGroup(C))
3655 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003656 }
3657
3658 return R;
3659 }
3660
3661 return getRawCursorExtent(C);
3662}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003663
3664extern "C" {
3665
3666CXSourceRange clang_getCursorExtent(CXCursor C) {
3667 SourceRange R = getRawCursorExtent(C);
3668 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003669 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003670
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003671 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003672}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003673
3674CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003675 if (clang_isInvalid(C.kind))
3676 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003677
Ted Kremeneka60ed472010-11-16 08:15:36 +00003678 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003679 if (clang_isDeclaration(C.kind)) {
3680 Decl *D = getCursorDecl(C);
3681 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003682 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003683 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003684 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003685 if (ObjCForwardProtocolDecl *Protocols
3686 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003687 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003688 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3689 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3690 return MakeCXCursor(Property, tu);
3691
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003692 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003693 }
3694
Douglas Gregor97b98722010-01-19 23:20:36 +00003695 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003696 Expr *E = getCursorExpr(C);
3697 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003698 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003699 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003700
3701 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003702 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003703
Douglas Gregor97b98722010-01-19 23:20:36 +00003704 return clang_getNullCursor();
3705 }
3706
Douglas Gregor36897b02010-09-10 00:22:18 +00003707 if (clang_isStatement(C.kind)) {
3708 Stmt *S = getCursorStmt(C);
3709 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003710 return MakeCXCursor(Goto->getLabel()->getStmt(), getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003711
3712 return clang_getNullCursor();
3713 }
3714
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003715 if (C.kind == CXCursor_MacroInstantiation) {
3716 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003717 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003718 }
3719
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003720 if (!clang_isReference(C.kind))
3721 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003722
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003723 switch (C.kind) {
3724 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003725 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003726
3727 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003728 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003729
3730 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003731 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003732
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003733 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003734 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003735
3736 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003737 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003738
Douglas Gregor69319002010-08-31 23:48:11 +00003739 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003740 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003741
Douglas Gregora67e03f2010-09-09 21:42:20 +00003742 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003743 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003744
Ted Kremenek3064ef92010-08-27 21:34:58 +00003745 case CXCursor_CXXBaseSpecifier: {
3746 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3747 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003748 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003749 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003750
Douglas Gregor36897b02010-09-10 00:22:18 +00003751 case CXCursor_LabelRef:
3752 // FIXME: We end up faking the "parent" declaration here because we
3753 // don't want to make CXCursor larger.
3754 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003755 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3756 .getTranslationUnitDecl(),
3757 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003758
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003759 case CXCursor_OverloadedDeclRef:
3760 return C;
3761
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003762 default:
3763 // We would prefer to enumerate all non-reference cursor kinds here.
3764 llvm_unreachable("Unhandled reference cursor kind");
3765 break;
3766 }
3767 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003768
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003769 return clang_getNullCursor();
3770}
3771
Douglas Gregorb6998662010-01-19 19:34:47 +00003772CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003773 if (clang_isInvalid(C.kind))
3774 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003775
Ted Kremeneka60ed472010-11-16 08:15:36 +00003776 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003777
Douglas Gregorb6998662010-01-19 19:34:47 +00003778 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003779 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003780 C = clang_getCursorReferenced(C);
3781 WasReference = true;
3782 }
3783
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003784 if (C.kind == CXCursor_MacroInstantiation)
3785 return clang_getCursorReferenced(C);
3786
Douglas Gregorb6998662010-01-19 19:34:47 +00003787 if (!clang_isDeclaration(C.kind))
3788 return clang_getNullCursor();
3789
3790 Decl *D = getCursorDecl(C);
3791 if (!D)
3792 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003793
Douglas Gregorb6998662010-01-19 19:34:47 +00003794 switch (D->getKind()) {
3795 // Declaration kinds that don't really separate the notions of
3796 // declaration and definition.
3797 case Decl::Namespace:
3798 case Decl::Typedef:
3799 case Decl::TemplateTypeParm:
3800 case Decl::EnumConstant:
3801 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003802 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003803 case Decl::ObjCIvar:
3804 case Decl::ObjCAtDefsField:
3805 case Decl::ImplicitParam:
3806 case Decl::ParmVar:
3807 case Decl::NonTypeTemplateParm:
3808 case Decl::TemplateTemplateParm:
3809 case Decl::ObjCCategoryImpl:
3810 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003811 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003812 case Decl::LinkageSpec:
3813 case Decl::ObjCPropertyImpl:
3814 case Decl::FileScopeAsm:
3815 case Decl::StaticAssert:
3816 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003817 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003818 return C;
3819
3820 // Declaration kinds that don't make any sense here, but are
3821 // nonetheless harmless.
3822 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003823 break;
3824
3825 // Declaration kinds for which the definition is not resolvable.
3826 case Decl::UnresolvedUsingTypename:
3827 case Decl::UnresolvedUsingValue:
3828 break;
3829
3830 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003831 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003832 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003833
3834 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003835 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003836
3837 case Decl::Enum:
3838 case Decl::Record:
3839 case Decl::CXXRecord:
3840 case Decl::ClassTemplateSpecialization:
3841 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003842 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003843 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003844 return clang_getNullCursor();
3845
3846 case Decl::Function:
3847 case Decl::CXXMethod:
3848 case Decl::CXXConstructor:
3849 case Decl::CXXDestructor:
3850 case Decl::CXXConversion: {
3851 const FunctionDecl *Def = 0;
3852 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003853 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003854 return clang_getNullCursor();
3855 }
3856
3857 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003858 // Ask the variable if it has a definition.
3859 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003860 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003861 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003862 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003863
Douglas Gregorb6998662010-01-19 19:34:47 +00003864 case Decl::FunctionTemplate: {
3865 const FunctionDecl *Def = 0;
3866 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003867 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003868 return clang_getNullCursor();
3869 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003870
Douglas Gregorb6998662010-01-19 19:34:47 +00003871 case Decl::ClassTemplate: {
3872 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003873 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003874 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003875 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003876 return clang_getNullCursor();
3877 }
3878
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003879 case Decl::Using:
3880 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003881 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003882
3883 case Decl::UsingShadow:
3884 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003885 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003886 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003887
3888 case Decl::ObjCMethod: {
3889 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3890 if (Method->isThisDeclarationADefinition())
3891 return C;
3892
3893 // Dig out the method definition in the associated
3894 // @implementation, if we have it.
3895 // FIXME: The ASTs should make finding the definition easier.
3896 if (ObjCInterfaceDecl *Class
3897 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3898 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3899 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3900 Method->isInstanceMethod()))
3901 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003902 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003903
3904 return clang_getNullCursor();
3905 }
3906
3907 case Decl::ObjCCategory:
3908 if (ObjCCategoryImplDecl *Impl
3909 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003910 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003911 return clang_getNullCursor();
3912
3913 case Decl::ObjCProtocol:
3914 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3915 return C;
3916 return clang_getNullCursor();
3917
3918 case Decl::ObjCInterface:
3919 // There are two notions of a "definition" for an Objective-C
3920 // class: the interface and its implementation. When we resolved a
3921 // reference to an Objective-C class, produce the @interface as
3922 // the definition; when we were provided with the interface,
3923 // produce the @implementation as the definition.
3924 if (WasReference) {
3925 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
3926 return C;
3927 } else if (ObjCImplementationDecl *Impl
3928 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003929 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003930 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003931
Douglas Gregorb6998662010-01-19 19:34:47 +00003932 case Decl::ObjCProperty:
3933 // FIXME: We don't really know where to find the
3934 // ObjCPropertyImplDecls that implement this property.
3935 return clang_getNullCursor();
3936
3937 case Decl::ObjCCompatibleAlias:
3938 if (ObjCInterfaceDecl *Class
3939 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
3940 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003941 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003942
Douglas Gregorb6998662010-01-19 19:34:47 +00003943 return clang_getNullCursor();
3944
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003945 case Decl::ObjCForwardProtocol:
3946 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003947 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003948
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003949 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00003950 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003951 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003952
3953 case Decl::Friend:
3954 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003955 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003956 return clang_getNullCursor();
3957
3958 case Decl::FriendTemplate:
3959 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003960 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003961 return clang_getNullCursor();
3962 }
3963
3964 return clang_getNullCursor();
3965}
3966
3967unsigned clang_isCursorDefinition(CXCursor C) {
3968 if (!clang_isDeclaration(C.kind))
3969 return 0;
3970
3971 return clang_getCursorDefinition(C) == C;
3972}
3973
Douglas Gregor1a9d0502010-11-19 23:44:15 +00003974CXCursor clang_getCanonicalCursor(CXCursor C) {
3975 if (!clang_isDeclaration(C.kind))
3976 return C;
3977
3978 if (Decl *D = getCursorDecl(C))
3979 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
3980
3981 return C;
3982}
3983
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003984unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00003985 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003986 return 0;
3987
3988 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3989 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3990 return E->getNumDecls();
3991
3992 if (OverloadedTemplateStorage *S
3993 = Storage.dyn_cast<OverloadedTemplateStorage*>())
3994 return S->size();
3995
3996 Decl *D = Storage.get<Decl*>();
3997 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00003998 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003999 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4000 return Classes->size();
4001 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4002 return Protocols->protocol_size();
4003
4004 return 0;
4005}
4006
4007CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004008 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004009 return clang_getNullCursor();
4010
4011 if (index >= clang_getNumOverloadedDecls(cursor))
4012 return clang_getNullCursor();
4013
Ted Kremeneka60ed472010-11-16 08:15:36 +00004014 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004015 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4016 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004017 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004018
4019 if (OverloadedTemplateStorage *S
4020 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004021 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004022
4023 Decl *D = Storage.get<Decl*>();
4024 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4025 // FIXME: This is, unfortunately, linear time.
4026 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4027 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004028 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004029 }
4030
4031 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004032 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004033
4034 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004035 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004036
4037 return clang_getNullCursor();
4038}
4039
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004040void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004041 const char **startBuf,
4042 const char **endBuf,
4043 unsigned *startLine,
4044 unsigned *startColumn,
4045 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004046 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004047 assert(getCursorDecl(C) && "CXCursor has null decl");
4048 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004049 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4050 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004051
Steve Naroff4ade6d62009-09-23 17:52:52 +00004052 SourceManager &SM = FD->getASTContext().getSourceManager();
4053 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4054 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4055 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4056 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4057 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4058 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4059}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004060
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004061void clang_enableStackTraces(void) {
4062 llvm::sys::PrintStackTraceOnErrorSignal();
4063}
4064
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004065void clang_executeOnThread(void (*fn)(void*), void *user_data,
4066 unsigned stack_size) {
4067 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4068}
4069
Ted Kremenekfb480492010-01-13 21:46:36 +00004070} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004071
Ted Kremenekfb480492010-01-13 21:46:36 +00004072//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004073// Token-based Operations.
4074//===----------------------------------------------------------------------===//
4075
4076/* CXToken layout:
4077 * int_data[0]: a CXTokenKind
4078 * int_data[1]: starting token location
4079 * int_data[2]: token length
4080 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004081 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004082 * otherwise unused.
4083 */
4084extern "C" {
4085
4086CXTokenKind clang_getTokenKind(CXToken CXTok) {
4087 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4088}
4089
4090CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4091 switch (clang_getTokenKind(CXTok)) {
4092 case CXToken_Identifier:
4093 case CXToken_Keyword:
4094 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004095 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4096 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004097
4098 case CXToken_Literal: {
4099 // We have stashed the starting pointer in the ptr_data field. Use it.
4100 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004101 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004102 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004103
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004104 case CXToken_Punctuation:
4105 case CXToken_Comment:
4106 break;
4107 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004108
4109 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004110 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004111 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004112 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004113 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004114
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004115 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4116 std::pair<FileID, unsigned> LocInfo
4117 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004118 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004119 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004120 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4121 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004122 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004123
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004124 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004125}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004126
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004127CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004128 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004129 if (!CXXUnit)
4130 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004131
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004132 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4133 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4134}
4135
4136CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004137 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004138 if (!CXXUnit)
4139 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004140
4141 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004142 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4143}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004144
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004145void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4146 CXToken **Tokens, unsigned *NumTokens) {
4147 if (Tokens)
4148 *Tokens = 0;
4149 if (NumTokens)
4150 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004151
Ted Kremeneka60ed472010-11-16 08:15:36 +00004152 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004153 if (!CXXUnit || !Tokens || !NumTokens)
4154 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004155
Douglas Gregorbdf60622010-03-05 21:16:25 +00004156 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4157
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004158 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004159 if (R.isInvalid())
4160 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004161
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004162 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4163 std::pair<FileID, unsigned> BeginLocInfo
4164 = SourceMgr.getDecomposedLoc(R.getBegin());
4165 std::pair<FileID, unsigned> EndLocInfo
4166 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004167
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004168 // Cannot tokenize across files.
4169 if (BeginLocInfo.first != EndLocInfo.first)
4170 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004171
4172 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004173 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004174 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004175 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004176 if (Invalid)
4177 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004178
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004179 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4180 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004181 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004182 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004183
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004184 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004185 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004186 llvm::SmallVector<CXToken, 32> CXTokens;
4187 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004188 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004189 do {
4190 // Lex the next token
4191 Lex.LexFromRawLexer(Tok);
4192 if (Tok.is(tok::eof))
4193 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004194
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004195 // Initialize the CXToken.
4196 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004197
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004198 // - Common fields
4199 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4200 CXTok.int_data[2] = Tok.getLength();
4201 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004202
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004203 // - Kind-specific fields
4204 if (Tok.isLiteral()) {
4205 CXTok.int_data[0] = CXToken_Literal;
4206 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004207 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004208 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004209 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004210 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004211
David Chisnall096428b2010-10-13 21:44:48 +00004212 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004213 CXTok.int_data[0] = CXToken_Keyword;
4214 }
4215 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004216 CXTok.int_data[0] = Tok.is(tok::identifier)
4217 ? CXToken_Identifier
4218 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004219 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004220 CXTok.ptr_data = II;
4221 } else if (Tok.is(tok::comment)) {
4222 CXTok.int_data[0] = CXToken_Comment;
4223 CXTok.ptr_data = 0;
4224 } else {
4225 CXTok.int_data[0] = CXToken_Punctuation;
4226 CXTok.ptr_data = 0;
4227 }
4228 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004229 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004230 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004231
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004232 if (CXTokens.empty())
4233 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004234
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004235 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4236 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4237 *NumTokens = CXTokens.size();
4238}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004239
Ted Kremenek6db61092010-05-05 00:55:15 +00004240void clang_disposeTokens(CXTranslationUnit TU,
4241 CXToken *Tokens, unsigned NumTokens) {
4242 free(Tokens);
4243}
4244
4245} // end: extern "C"
4246
4247//===----------------------------------------------------------------------===//
4248// Token annotation APIs.
4249//===----------------------------------------------------------------------===//
4250
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004251typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004252static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4253 CXCursor parent,
4254 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004255namespace {
4256class AnnotateTokensWorker {
4257 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004258 CXToken *Tokens;
4259 CXCursor *Cursors;
4260 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004261 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004262 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004263 CursorVisitor AnnotateVis;
4264 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004265 bool HasContextSensitiveKeywords;
4266
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004267 bool MoreTokens() const { return TokIdx < NumTokens; }
4268 unsigned NextToken() const { return TokIdx; }
4269 void AdvanceToken() { ++TokIdx; }
4270 SourceLocation GetTokenLoc(unsigned tokI) {
4271 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4272 }
4273
Ted Kremenek6db61092010-05-05 00:55:15 +00004274public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004275 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004276 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004277 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004278 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004279 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004280 AnnotateVis(tu,
4281 AnnotateTokensVisitor, this,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004282 Decl::MaxPCHLevel, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004283 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4284 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004285
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004286 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004287 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004288 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004289 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004290 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004291 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004292
4293 /// \brief Determine whether the annotator saw any cursors that have
4294 /// context-sensitive keywords.
4295 bool hasContextSensitiveKeywords() const {
4296 return HasContextSensitiveKeywords;
4297 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004298};
4299}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004300
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004301void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4302 // Walk the AST within the region of interest, annotating tokens
4303 // along the way.
4304 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004305
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004306 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4307 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004308 if (Pos != Annotated.end() &&
4309 (clang_isInvalid(Cursors[I].kind) ||
4310 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004311 Cursors[I] = Pos->second;
4312 }
4313
4314 // Finish up annotating any tokens left.
4315 if (!MoreTokens())
4316 return;
4317
4318 const CXCursor &C = clang_getNullCursor();
4319 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4320 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4321 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004322 }
4323}
4324
Ted Kremenek6db61092010-05-05 00:55:15 +00004325enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004326AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004327 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004328 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004329 if (cursorRange.isInvalid())
4330 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004331
4332 if (!HasContextSensitiveKeywords) {
4333 // Objective-C properties can have context-sensitive keywords.
4334 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4335 if (ObjCPropertyDecl *Property
4336 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4337 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4338 }
4339 // Objective-C methods can have context-sensitive keywords.
4340 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4341 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4342 if (ObjCMethodDecl *Method
4343 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4344 if (Method->getObjCDeclQualifier())
4345 HasContextSensitiveKeywords = true;
4346 else {
4347 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4348 PEnd = Method->param_end();
4349 P != PEnd; ++P) {
4350 if ((*P)->getObjCDeclQualifier()) {
4351 HasContextSensitiveKeywords = true;
4352 break;
4353 }
4354 }
4355 }
4356 }
4357 }
4358 // C++ methods can have context-sensitive keywords.
4359 else if (cursor.kind == CXCursor_CXXMethod) {
4360 if (CXXMethodDecl *Method
4361 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4362 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4363 HasContextSensitiveKeywords = true;
4364 }
4365 }
4366 // C++ classes can have context-sensitive keywords.
4367 else if (cursor.kind == CXCursor_StructDecl ||
4368 cursor.kind == CXCursor_ClassDecl ||
4369 cursor.kind == CXCursor_ClassTemplate ||
4370 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4371 if (Decl *D = getCursorDecl(cursor))
4372 if (D->hasAttr<FinalAttr>())
4373 HasContextSensitiveKeywords = true;
4374 }
4375 }
4376
Douglas Gregor4419b672010-10-21 06:10:04 +00004377 if (clang_isPreprocessing(cursor.kind)) {
4378 // For macro instantiations, just note where the beginning of the macro
4379 // instantiation occurs.
4380 if (cursor.kind == CXCursor_MacroInstantiation) {
4381 Annotated[Loc.int_data] = cursor;
4382 return CXChildVisit_Recurse;
4383 }
4384
Douglas Gregor4419b672010-10-21 06:10:04 +00004385 // Items in the preprocessing record are kept separate from items in
4386 // declarations, so we keep a separate token index.
4387 unsigned SavedTokIdx = TokIdx;
4388 TokIdx = PreprocessingTokIdx;
4389
4390 // Skip tokens up until we catch up to the beginning of the preprocessing
4391 // entry.
4392 while (MoreTokens()) {
4393 const unsigned I = NextToken();
4394 SourceLocation TokLoc = GetTokenLoc(I);
4395 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4396 case RangeBefore:
4397 AdvanceToken();
4398 continue;
4399 case RangeAfter:
4400 case RangeOverlap:
4401 break;
4402 }
4403 break;
4404 }
4405
4406 // Look at all of the tokens within this range.
4407 while (MoreTokens()) {
4408 const unsigned I = NextToken();
4409 SourceLocation TokLoc = GetTokenLoc(I);
4410 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4411 case RangeBefore:
4412 assert(0 && "Infeasible");
4413 case RangeAfter:
4414 break;
4415 case RangeOverlap:
4416 Cursors[I] = cursor;
4417 AdvanceToken();
4418 continue;
4419 }
4420 break;
4421 }
4422
4423 // Save the preprocessing token index; restore the non-preprocessing
4424 // token index.
4425 PreprocessingTokIdx = TokIdx;
4426 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004427 return CXChildVisit_Recurse;
4428 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004429
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004430 if (cursorRange.isInvalid())
4431 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004432
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004433 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4434
Ted Kremeneka333c662010-05-12 05:29:33 +00004435 // Adjust the annotated range based specific declarations.
4436 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4437 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004438 Decl *D = cxcursor::getCursorDecl(cursor);
4439 // Don't visit synthesized ObjC methods, since they have no syntatic
4440 // representation in the source.
4441 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4442 if (MD->isSynthesized())
4443 return CXChildVisit_Continue;
4444 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004445
4446 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004447 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004448 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4449 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4450 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4451 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4452 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004453 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004454
4455 if (StartLoc.isValid() && L.isValid() &&
4456 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4457 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004458 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004459
Ted Kremenek3f404602010-08-14 01:14:06 +00004460 // If the location of the cursor occurs within a macro instantiation, record
4461 // the spelling location of the cursor in our annotation map. We can then
4462 // paper over the token labelings during a post-processing step to try and
4463 // get cursor mappings for tokens that are the *arguments* of a macro
4464 // instantiation.
4465 if (L.isMacroID()) {
4466 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4467 // Only invalidate the old annotation if it isn't part of a preprocessing
4468 // directive. Here we assume that the default construction of CXCursor
4469 // results in CXCursor.kind being an initialized value (i.e., 0). If
4470 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004471
Ted Kremenek3f404602010-08-14 01:14:06 +00004472 CXCursor &oldC = Annotated[rawEncoding];
4473 if (!clang_isPreprocessing(oldC.kind))
4474 oldC = cursor;
4475 }
4476
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004477 const enum CXCursorKind K = clang_getCursorKind(parent);
4478 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004479 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4480 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004481
4482 while (MoreTokens()) {
4483 const unsigned I = NextToken();
4484 SourceLocation TokLoc = GetTokenLoc(I);
4485 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4486 case RangeBefore:
4487 Cursors[I] = updateC;
4488 AdvanceToken();
4489 continue;
4490 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004491 case RangeOverlap:
4492 break;
4493 }
4494 break;
4495 }
4496
4497 // Visit children to get their cursor information.
4498 const unsigned BeforeChildren = NextToken();
4499 VisitChildren(cursor);
4500 const unsigned AfterChildren = NextToken();
4501
4502 // Adjust 'Last' to the last token within the extent of the cursor.
4503 while (MoreTokens()) {
4504 const unsigned I = NextToken();
4505 SourceLocation TokLoc = GetTokenLoc(I);
4506 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4507 case RangeBefore:
4508 assert(0 && "Infeasible");
4509 case RangeAfter:
4510 break;
4511 case RangeOverlap:
4512 Cursors[I] = updateC;
4513 AdvanceToken();
4514 continue;
4515 }
4516 break;
4517 }
4518 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004519
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004520 // Scan the tokens that are at the beginning of the cursor, but are not
4521 // capture by the child cursors.
4522
4523 // For AST elements within macros, rely on a post-annotate pass to
4524 // to correctly annotate the tokens with cursors. Otherwise we can
4525 // get confusing results of having tokens that map to cursors that really
4526 // are expanded by an instantiation.
4527 if (L.isMacroID())
4528 cursor = clang_getNullCursor();
4529
4530 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4531 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4532 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004533
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004534 Cursors[I] = cursor;
4535 }
4536 // Scan the tokens that are at the end of the cursor, but are not captured
4537 // but the child cursors.
4538 for (unsigned I = AfterChildren; I != Last; ++I)
4539 Cursors[I] = cursor;
4540
4541 TokIdx = Last;
4542 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004543}
4544
Ted Kremenek6db61092010-05-05 00:55:15 +00004545static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4546 CXCursor parent,
4547 CXClientData client_data) {
4548 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4549}
4550
Ted Kremenekab979612010-11-11 08:05:23 +00004551// This gets run a separate thread to avoid stack blowout.
4552static void runAnnotateTokensWorker(void *UserData) {
4553 ((AnnotateTokensWorker*)UserData)->AnnotateTokens();
4554}
4555
Ted Kremenek6db61092010-05-05 00:55:15 +00004556extern "C" {
4557
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004558void clang_annotateTokens(CXTranslationUnit TU,
4559 CXToken *Tokens, unsigned NumTokens,
4560 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004561
4562 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004563 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004564
Douglas Gregor4419b672010-10-21 06:10:04 +00004565 // Any token we don't specifically annotate will have a NULL cursor.
4566 CXCursor C = clang_getNullCursor();
4567 for (unsigned I = 0; I != NumTokens; ++I)
4568 Cursors[I] = C;
4569
Ted Kremeneka60ed472010-11-16 08:15:36 +00004570 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004571 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004572 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004573
Douglas Gregorbdf60622010-03-05 21:16:25 +00004574 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004575
Douglas Gregor0396f462010-03-19 05:22:59 +00004576 // Determine the region of interest, which contains all of the tokens.
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004577 SourceRange RegionOfInterest;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004578 RegionOfInterest.setBegin(cxloc::translateSourceLocation(
4579 clang_getTokenLocation(TU, Tokens[0])));
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00004580 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
4581 clang_getTokenLocation(TU,
4582 Tokens[NumTokens - 1])));
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004583
Douglas Gregor0396f462010-03-19 05:22:59 +00004584 // A mapping from the source locations found when re-lexing or traversing the
4585 // region of interest to the corresponding cursors.
4586 AnnotateTokensData Annotated;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004587
4588 // Relex the tokens within the source range to look for preprocessing
Douglas Gregor0396f462010-03-19 05:22:59 +00004589 // directives.
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004590 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4591 std::pair<FileID, unsigned> BeginLocInfo
4592 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4593 std::pair<FileID, unsigned> EndLocInfo
4594 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004595
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004596 llvm::StringRef Buffer;
Douglas Gregor0396f462010-03-19 05:22:59 +00004597 bool Invalid = false;
4598 if (BeginLocInfo.first == EndLocInfo.first &&
4599 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4600 !Invalid) {
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004601 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4602 CXXUnit->getASTContext().getLangOptions(),
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004603 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
Douglas Gregor4ae8f292010-03-18 17:52:52 +00004604 Buffer.end());
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004605 Lex.SetCommentRetentionState(true);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004606
4607 // Lex tokens in raw mode until we hit the end of the range, to avoid
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004608 // entering #includes or expanding macros.
Douglas Gregor48072312010-03-18 15:23:44 +00004609 while (true) {
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004610 Token Tok;
4611 Lex.LexFromRawLexer(Tok);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004612
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004613 reprocess:
4614 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4615 // We have found a preprocessing directive. Gobble it up so that we
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004616 // don't see it while preprocessing these tokens later, but keep track
4617 // of all of the token locations inside this preprocessing directive so
4618 // that we can annotate them appropriately.
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004619 //
4620 // FIXME: Some simple tests here could identify macro definitions and
4621 // #undefs, to provide specific cursor kinds for those.
4622 std::vector<SourceLocation> Locations;
4623 do {
4624 Locations.push_back(Tok.getLocation());
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004625 Lex.LexFromRawLexer(Tok);
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004626 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004627
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004628 using namespace cxcursor;
4629 CXCursor Cursor
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004630 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4631 Locations.back()),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004632 TU);
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004633 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4634 Annotated[Locations[I].getRawEncoding()] = Cursor;
4635 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004636
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004637 if (Tok.isAtStartOfLine())
4638 goto reprocess;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004639
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004640 continue;
4641 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004642
Douglas Gregor48072312010-03-18 15:23:44 +00004643 if (Tok.is(tok::eof))
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004644 break;
4645 }
Douglas Gregor4ae8f292010-03-18 17:52:52 +00004646 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004647
Douglas Gregor0396f462010-03-19 05:22:59 +00004648 // Annotate all of the source locations in the region of interest that map to
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004649 // a specific cursor.
4650 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004651 TU, RegionOfInterest);
Ted Kremenekab979612010-11-11 08:05:23 +00004652
4653 // Run the worker within a CrashRecoveryContext.
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004654 // FIXME: We use a ridiculous stack size here because the data-recursion
4655 // algorithm uses a large stack frame than the non-data recursive version,
4656 // and AnnotationTokensWorker currently transforms the data-recursion
4657 // algorithm back into a traditional recursion by explicitly calling
4658 // VisitChildren(). We will need to remove this explicit recursive call.
Ted Kremenekab979612010-11-11 08:05:23 +00004659 llvm::CrashRecoveryContext CRC;
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004660 if (!RunSafely(CRC, runAnnotateTokensWorker, &W,
4661 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004662 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4663 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004664
4665 // If we ran into any entities that involve context-sensitive keywords,
4666 // take another pass through the tokens to mark them as such.
4667 if (W.hasContextSensitiveKeywords()) {
4668 for (unsigned I = 0; I != NumTokens; ++I) {
4669 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4670 continue;
4671
4672 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4673 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4674 if (ObjCPropertyDecl *Property
4675 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4676 if (Property->getPropertyAttributesAsWritten() != 0 &&
4677 llvm::StringSwitch<bool>(II->getName())
4678 .Case("readonly", true)
4679 .Case("assign", true)
4680 .Case("readwrite", true)
4681 .Case("retain", true)
4682 .Case("copy", true)
4683 .Case("nonatomic", true)
4684 .Case("atomic", true)
4685 .Case("getter", true)
4686 .Case("setter", true)
4687 .Default(false))
4688 Tokens[I].int_data[0] = CXToken_Keyword;
4689 }
4690 continue;
4691 }
4692
4693 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4694 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4695 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4696 if (llvm::StringSwitch<bool>(II->getName())
4697 .Case("in", true)
4698 .Case("out", true)
4699 .Case("inout", true)
4700 .Case("oneway", true)
4701 .Case("bycopy", true)
4702 .Case("byref", true)
4703 .Default(false))
4704 Tokens[I].int_data[0] = CXToken_Keyword;
4705 continue;
4706 }
4707
4708 if (Cursors[I].kind == CXCursor_CXXMethod) {
4709 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4710 if (CXXMethodDecl *Method
4711 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4712 if ((Method->hasAttr<FinalAttr>() ||
4713 Method->hasAttr<OverrideAttr>()) &&
4714 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4715 llvm::StringSwitch<bool>(II->getName())
4716 .Case("final", true)
4717 .Case("override", true)
4718 .Default(false))
4719 Tokens[I].int_data[0] = CXToken_Keyword;
4720 }
4721 continue;
4722 }
4723
4724 if (Cursors[I].kind == CXCursor_ClassDecl ||
4725 Cursors[I].kind == CXCursor_StructDecl ||
4726 Cursors[I].kind == CXCursor_ClassTemplate) {
4727 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4728 if (II->getName() == "final") {
4729 // We have to be careful with 'final', since it could be the name
4730 // of a member class rather than the context-sensitive keyword.
4731 // So, check whether the cursor associated with this
4732 Decl *D = getCursorDecl(Cursors[I]);
4733 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4734 if ((Record->hasAttr<FinalAttr>()) &&
4735 Record->getIdentifier() != II)
4736 Tokens[I].int_data[0] = CXToken_Keyword;
4737 } else if (ClassTemplateDecl *ClassTemplate
4738 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4739 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4740 if ((Record->hasAttr<FinalAttr>()) &&
4741 Record->getIdentifier() != II)
4742 Tokens[I].int_data[0] = CXToken_Keyword;
4743 }
4744 }
4745 continue;
4746 }
4747 }
4748 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004749}
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004750} // end: extern "C"
4751
4752//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004753// Operations for querying linkage of a cursor.
4754//===----------------------------------------------------------------------===//
4755
4756extern "C" {
4757CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004758 if (!clang_isDeclaration(cursor.kind))
4759 return CXLinkage_Invalid;
4760
Ted Kremenek16b42592010-03-03 06:36:57 +00004761 Decl *D = cxcursor::getCursorDecl(cursor);
4762 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4763 switch (ND->getLinkage()) {
4764 case NoLinkage: return CXLinkage_NoLinkage;
4765 case InternalLinkage: return CXLinkage_Internal;
4766 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4767 case ExternalLinkage: return CXLinkage_External;
4768 };
4769
4770 return CXLinkage_Invalid;
4771}
4772} // end: extern "C"
4773
4774//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004775// Operations for querying language of a cursor.
4776//===----------------------------------------------------------------------===//
4777
4778static CXLanguageKind getDeclLanguage(const Decl *D) {
4779 switch (D->getKind()) {
4780 default:
4781 break;
4782 case Decl::ImplicitParam:
4783 case Decl::ObjCAtDefsField:
4784 case Decl::ObjCCategory:
4785 case Decl::ObjCCategoryImpl:
4786 case Decl::ObjCClass:
4787 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004788 case Decl::ObjCForwardProtocol:
4789 case Decl::ObjCImplementation:
4790 case Decl::ObjCInterface:
4791 case Decl::ObjCIvar:
4792 case Decl::ObjCMethod:
4793 case Decl::ObjCProperty:
4794 case Decl::ObjCPropertyImpl:
4795 case Decl::ObjCProtocol:
4796 return CXLanguage_ObjC;
4797 case Decl::CXXConstructor:
4798 case Decl::CXXConversion:
4799 case Decl::CXXDestructor:
4800 case Decl::CXXMethod:
4801 case Decl::CXXRecord:
4802 case Decl::ClassTemplate:
4803 case Decl::ClassTemplatePartialSpecialization:
4804 case Decl::ClassTemplateSpecialization:
4805 case Decl::Friend:
4806 case Decl::FriendTemplate:
4807 case Decl::FunctionTemplate:
4808 case Decl::LinkageSpec:
4809 case Decl::Namespace:
4810 case Decl::NamespaceAlias:
4811 case Decl::NonTypeTemplateParm:
4812 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004813 case Decl::TemplateTemplateParm:
4814 case Decl::TemplateTypeParm:
4815 case Decl::UnresolvedUsingTypename:
4816 case Decl::UnresolvedUsingValue:
4817 case Decl::Using:
4818 case Decl::UsingDirective:
4819 case Decl::UsingShadow:
4820 return CXLanguage_CPlusPlus;
4821 }
4822
4823 return CXLanguage_C;
4824}
4825
4826extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004827
4828enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4829 if (clang_isDeclaration(cursor.kind))
4830 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
4831 if (D->hasAttr<UnavailableAttr>() ||
4832 (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()))
4833 return CXAvailability_Available;
4834
4835 if (D->hasAttr<DeprecatedAttr>())
4836 return CXAvailability_Deprecated;
4837 }
4838
4839 return CXAvailability_Available;
4840}
4841
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004842CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4843 if (clang_isDeclaration(cursor.kind))
4844 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4845
4846 return CXLanguage_Invalid;
4847}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004848
4849 /// \brief If the given cursor is the "templated" declaration
4850 /// descibing a class or function template, return the class or
4851 /// function template.
4852static Decl *maybeGetTemplateCursor(Decl *D) {
4853 if (!D)
4854 return 0;
4855
4856 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4857 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4858 return FunTmpl;
4859
4860 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4861 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4862 return ClassTmpl;
4863
4864 return D;
4865}
4866
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004867CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4868 if (clang_isDeclaration(cursor.kind)) {
4869 if (Decl *D = getCursorDecl(cursor)) {
4870 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004871 if (!DC)
4872 return clang_getNullCursor();
4873
4874 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4875 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004876 }
4877 }
4878
4879 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4880 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004881 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004882 }
4883
4884 return clang_getNullCursor();
4885}
4886
4887CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4888 if (clang_isDeclaration(cursor.kind)) {
4889 if (Decl *D = getCursorDecl(cursor)) {
4890 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004891 if (!DC)
4892 return clang_getNullCursor();
4893
4894 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4895 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004896 }
4897 }
4898
4899 // FIXME: Note that we can't easily compute the lexical context of a
4900 // statement or expression, so we return nothing.
4901 return clang_getNullCursor();
4902}
4903
Douglas Gregor9f592342010-10-01 20:25:15 +00004904static void CollectOverriddenMethods(DeclContext *Ctx,
4905 ObjCMethodDecl *Method,
4906 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
4907 if (!Ctx)
4908 return;
4909
4910 // If we have a class or category implementation, jump straight to the
4911 // interface.
4912 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
4913 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
4914
4915 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
4916 if (!Container)
4917 return;
4918
4919 // Check whether we have a matching method at this level.
4920 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
4921 Method->isInstanceMethod()))
4922 if (Method != Overridden) {
4923 // We found an override at this level; there is no need to look
4924 // into other protocols or categories.
4925 Methods.push_back(Overridden);
4926 return;
4927 }
4928
4929 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4930 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
4931 PEnd = Protocol->protocol_end();
4932 P != PEnd; ++P)
4933 CollectOverriddenMethods(*P, Method, Methods);
4934 }
4935
4936 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4937 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
4938 PEnd = Category->protocol_end();
4939 P != PEnd; ++P)
4940 CollectOverriddenMethods(*P, Method, Methods);
4941 }
4942
4943 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
4944 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
4945 PEnd = Interface->protocol_end();
4946 P != PEnd; ++P)
4947 CollectOverriddenMethods(*P, Method, Methods);
4948
4949 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
4950 Category; Category = Category->getNextClassCategory())
4951 CollectOverriddenMethods(Category, Method, Methods);
4952
4953 // We only look into the superclass if we haven't found anything yet.
4954 if (Methods.empty())
4955 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
4956 return CollectOverriddenMethods(Super, Method, Methods);
4957 }
4958}
4959
4960void clang_getOverriddenCursors(CXCursor cursor,
4961 CXCursor **overridden,
4962 unsigned *num_overridden) {
4963 if (overridden)
4964 *overridden = 0;
4965 if (num_overridden)
4966 *num_overridden = 0;
4967 if (!overridden || !num_overridden)
4968 return;
4969
4970 if (!clang_isDeclaration(cursor.kind))
4971 return;
4972
4973 Decl *D = getCursorDecl(cursor);
4974 if (!D)
4975 return;
4976
4977 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004978 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00004979 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
4980 *num_overridden = CXXMethod->size_overridden_methods();
4981 if (!*num_overridden)
4982 return;
4983
4984 *overridden = new CXCursor [*num_overridden];
4985 unsigned I = 0;
4986 for (CXXMethodDecl::method_iterator
4987 M = CXXMethod->begin_overridden_methods(),
4988 MEnd = CXXMethod->end_overridden_methods();
4989 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00004990 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00004991 return;
4992 }
4993
4994 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
4995 if (!Method)
4996 return;
4997
4998 // Handle Objective-C methods.
4999 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5000 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5001
5002 if (Methods.empty())
5003 return;
5004
5005 *num_overridden = Methods.size();
5006 *overridden = new CXCursor [Methods.size()];
5007 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005008 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005009}
5010
5011void clang_disposeOverriddenCursors(CXCursor *overridden) {
5012 delete [] overridden;
5013}
5014
Douglas Gregorecdcb882010-10-20 22:00:55 +00005015CXFile clang_getIncludedFile(CXCursor cursor) {
5016 if (cursor.kind != CXCursor_InclusionDirective)
5017 return 0;
5018
5019 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5020 return (void *)ID->getFile();
5021}
5022
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005023} // end: extern "C"
5024
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005025
5026//===----------------------------------------------------------------------===//
5027// C++ AST instrospection.
5028//===----------------------------------------------------------------------===//
5029
5030extern "C" {
5031unsigned clang_CXXMethod_isStatic(CXCursor C) {
5032 if (!clang_isDeclaration(C.kind))
5033 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005034
5035 CXXMethodDecl *Method = 0;
5036 Decl *D = cxcursor::getCursorDecl(C);
5037 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5038 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5039 else
5040 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5041 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005042}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005043
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005044} // end: extern "C"
5045
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005046//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005047// Attribute introspection.
5048//===----------------------------------------------------------------------===//
5049
5050extern "C" {
5051CXType clang_getIBOutletCollectionType(CXCursor C) {
5052 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005053 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005054
5055 IBOutletCollectionAttr *A =
5056 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5057
Douglas Gregor841b2382011-03-06 18:55:32 +00005058 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005059}
5060} // end: extern "C"
5061
5062//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005063// Misc. utility functions.
5064//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005065
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005066/// Default to using an 8 MB stack size on "safety" threads.
5067static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005068
5069namespace clang {
5070
5071bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005072 void (*Fn)(void*), void *UserData,
5073 unsigned Size) {
5074 if (!Size)
5075 Size = GetSafetyThreadStackSize();
5076 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005077 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5078 return CRC.RunSafely(Fn, UserData);
5079}
5080
5081unsigned GetSafetyThreadStackSize() {
5082 return SafetyStackThreadSize;
5083}
5084
5085void SetSafetyThreadStackSize(unsigned Value) {
5086 SafetyStackThreadSize = Value;
5087}
5088
5089}
5090
Ted Kremenek04bb7162010-01-22 22:44:15 +00005091extern "C" {
5092
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005093CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005094 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005095}
5096
5097} // end: extern "C"