blob: 290146fa4dd1035cbabc6df716a657d4089c9ea7 [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);
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00001752 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *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:
Abramo Bagnara06dec892011-03-12 09:45:03 +00002003 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenekcdba6592010-11-18 00:42:18 +00002004 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}
Peter Collingbournef4e3cfb2011-03-11 19:24:49 +00002017void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2018 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek6d0a00d2010-11-17 02:18:35 +00002019 EnqueueChildren(E);
2020 if (E->isArgumentType())
2021 AddTypeLoc(E->getArgumentTypeInfo());
2022}
Ted Kremenek28a71942010-11-13 00:36:47 +00002023void EnqueueVisitor::VisitStmt(Stmt *S) {
2024 EnqueueChildren(S);
2025}
2026void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2027 AddStmt(S->getBody());
2028 AddStmt(S->getCond());
2029 AddDecl(S->getConditionVariable());
2030}
Ted Kremenekfafa75a2010-11-17 00:50:39 +00002031
Ted Kremenek28a71942010-11-13 00:36:47 +00002032void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2033 AddStmt(W->getBody());
2034 AddStmt(W->getCond());
2035 AddDecl(W->getConditionVariable());
2036}
Ted Kremenek2939b6f2010-11-17 00:50:50 +00002037void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2038 AddTypeLoc(E->getQueriedTypeSourceInfo());
2039}
Francois Pichet6ad6f282010-12-07 00:08:36 +00002040
2041void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet6ad6f282010-12-07 00:08:36 +00002042 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichet0a03a3f2010-12-08 09:11:05 +00002043 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet6ad6f282010-12-07 00:08:36 +00002044}
2045
Ted Kremenek28a71942010-11-13 00:36:47 +00002046void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2047 VisitOverloadExpr(U);
2048 if (!U->isImplicitAccess())
2049 AddStmt(U->getBase());
2050}
Ted Kremenek9d3bf792010-11-17 00:50:43 +00002051void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2052 AddStmt(E->getSubExpr());
2053 AddTypeLoc(E->getWrittenTypeInfo());
2054}
Douglas Gregor94d96292011-01-19 20:34:17 +00002055void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2056 WL.push_back(SizeOfPackExprParts(E, Parent));
2057}
Ted Kremenek60458782010-11-12 21:34:16 +00002058
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002059void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenek28a71942010-11-13 00:36:47 +00002060 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002061}
2062
2063bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2064 if (RegionOfInterest.isValid()) {
2065 SourceRange Range = getRawCursorExtent(C);
2066 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2067 return false;
2068 }
2069 return true;
2070}
2071
2072bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2073 while (!WL.empty()) {
2074 // Dequeue the worklist item.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002075 VisitorJob LI = WL.back();
2076 WL.pop_back();
2077
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002078 // Set the Parent field, then back to its old value once we're done.
2079 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2080
2081 switch (LI.getKind()) {
Ted Kremenekf1107452010-11-12 18:26:56 +00002082 case VisitorJob::DeclVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002083 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenekf1107452010-11-12 18:26:56 +00002084 if (!D)
2085 continue;
2086
2087 // For now, perform default visitation for Decls.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002088 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenekf1107452010-11-12 18:26:56 +00002089 return true;
2090
2091 continue;
2092 }
Ted Kremenek60608ec2010-11-17 00:50:47 +00002093 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2094 const ExplicitTemplateArgumentList *ArgList =
2095 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2096 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2097 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2098 Arg != ArgEnd; ++Arg) {
2099 if (VisitTemplateArgumentLoc(*Arg))
2100 return true;
2101 }
2102 continue;
2103 }
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002104 case VisitorJob::TypeLocVisitKind: {
2105 // Perform default visitation for TypeLocs.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002106 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremenekcdb4caf2010-11-12 21:34:12 +00002107 return true;
2108 continue;
2109 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002110 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002111 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremeneke7455012011-02-23 04:54:51 +00002112 if (LabelStmt *stmt = LS->getStmt()) {
2113 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2114 TU))) {
2115 return true;
2116 }
2117 }
Ted Kremenekae1fd6f2010-11-17 00:50:45 +00002118 continue;
2119 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002120
Ted Kremenekf64d8032010-11-18 00:02:32 +00002121 case VisitorJob::NestedNameSpecifierVisitKind: {
2122 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2123 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2124 return true;
2125 continue;
2126 }
Douglas Gregorf3db29f2011-02-25 18:19:59 +00002127
2128 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2129 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2130 if (VisitNestedNameSpecifierLoc(V->get()))
2131 return true;
2132 continue;
2133 }
2134
Ted Kremenekf64d8032010-11-18 00:02:32 +00002135 case VisitorJob::DeclarationNameInfoVisitKind: {
2136 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2137 ->get()))
2138 return true;
2139 continue;
2140 }
Ted Kremenekcdba6592010-11-18 00:42:18 +00002141 case VisitorJob::MemberRefVisitKind: {
2142 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2143 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2144 return true;
2145 continue;
2146 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002147 case VisitorJob::StmtVisitKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002148 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek8c269ac2010-11-11 23:11:43 +00002149 if (!S)
2150 continue;
2151
Ted Kremenekf1107452010-11-12 18:26:56 +00002152 // Update the current cursor.
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002153 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenekcdba6592010-11-18 00:42:18 +00002154 if (!IsInRegionOfInterest(Cursor))
2155 continue;
2156 switch (Visitor(Cursor, Parent, ClientData)) {
2157 case CXChildVisit_Break: return true;
2158 case CXChildVisit_Continue: break;
2159 case CXChildVisit_Recurse:
2160 EnqueueWorkList(WL, S);
Ted Kremenek82f3c502010-11-15 22:23:26 +00002161 break;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002162 }
Ted Kremenek82f3c502010-11-15 22:23:26 +00002163 continue;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002164 }
2165 case VisitorJob::MemberExprPartsKind: {
2166 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremenek82f3c502010-11-15 22:23:26 +00002167 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002168
2169 // Visit the nested-name-specifier
Douglas Gregor40d96a62011-02-28 21:54:11 +00002170 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002172 return true;
2173
2174 // Visit the declaration name.
2175 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2176 return true;
2177
2178 // Visit the explicitly-specified template arguments, if any.
2179 if (M->hasExplicitTemplateArgs()) {
2180 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2181 *ArgEnd = Arg + M->getNumTemplateArgs();
2182 Arg != ArgEnd; ++Arg) {
2183 if (VisitTemplateArgumentLoc(*Arg))
2184 return true;
2185 }
2186 }
2187 continue;
2188 }
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002189 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002190 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002191 // Visit nested-name-specifier, if present.
Douglas Gregor40d96a62011-02-28 21:54:11 +00002192 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2193 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002194 return true;
2195 // Visit declaration name.
2196 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2197 return true;
Ted Kremeneke4979cc2010-11-13 00:58:18 +00002198 continue;
2199 }
Ted Kremenek60458782010-11-12 21:34:16 +00002200 case VisitorJob::OverloadExprPartsKind: {
Ted Kremenek82f3c502010-11-15 22:23:26 +00002201 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenek60458782010-11-12 21:34:16 +00002202 // Visit the nested-name-specifier.
Douglas Gregor4c9be892011-02-28 20:01:57 +00002203 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2204 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek60458782010-11-12 21:34:16 +00002205 return true;
2206 // Visit the declaration name.
2207 if (VisitDeclarationNameInfo(O->getNameInfo()))
2208 return true;
2209 // Visit the overloaded declaration reference.
2210 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2211 return true;
Ted Kremenek60458782010-11-12 21:34:16 +00002212 continue;
2213 }
Douglas Gregor94d96292011-01-19 20:34:17 +00002214 case VisitorJob::SizeOfPackExprPartsKind: {
2215 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2216 NamedDecl *Pack = E->getPack();
2217 if (isa<TemplateTypeParmDecl>(Pack)) {
2218 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2219 E->getPackLoc(), TU)))
2220 return true;
2221
2222 continue;
2223 }
2224
2225 if (isa<TemplateTemplateParmDecl>(Pack)) {
2226 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2227 E->getPackLoc(), TU)))
2228 return true;
2229
2230 continue;
2231 }
2232
2233 // Non-type template parameter packs and function parameter packs are
2234 // treated like DeclRefExpr cursors.
2235 continue;
2236 }
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002237 }
2238 }
2239 return false;
2240}
2241
Ted Kremenekcdba6592010-11-18 00:42:18 +00002242bool CursorVisitor::Visit(Stmt *S) {
Ted Kremenekd1ded662010-11-15 23:31:32 +00002243 VisitorWorkList *WL = 0;
2244 if (!WorkListFreeList.empty()) {
2245 WL = WorkListFreeList.back();
2246 WL->clear();
2247 WorkListFreeList.pop_back();
2248 }
2249 else {
2250 WL = new VisitorWorkList();
2251 WorkListCache.push_back(WL);
2252 }
2253 EnqueueWorkList(*WL, S);
2254 bool result = RunVisitorWorkList(*WL);
2255 WorkListFreeList.push_back(WL);
2256 return result;
Ted Kremenekc0e1d922010-11-11 08:05:18 +00002257}
2258
2259//===----------------------------------------------------------------------===//
2260// Misc. API hooks.
2261//===----------------------------------------------------------------------===//
2262
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002263static llvm::sys::Mutex EnableMultithreadingMutex;
2264static bool EnabledMultithreading;
2265
Benjamin Kramer5e4bc592009-10-18 16:11:04 +00002266extern "C" {
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002267CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2268 int displayDiagnostics) {
Daniel Dunbar48615ff2010-10-08 19:30:33 +00002269 // Disable pretty stack trace functionality, which will otherwise be a very
2270 // poor citizen of the world and set up all sorts of signal handlers.
2271 llvm::DisablePrettyStackTrace = true;
2272
Daniel Dunbarc7df4f32010-08-18 18:43:14 +00002273 // We use crash recovery to make some of our APIs more reliable, implicitly
2274 // enable it.
2275 llvm::CrashRecoveryContext::Enable();
2276
Douglas Gregor8c8d5412010-09-24 21:18:36 +00002277 // Enable support for multithreading in LLVM.
2278 {
2279 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2280 if (!EnabledMultithreading) {
2281 llvm::llvm_start_multithreaded();
2282 EnabledMultithreading = true;
2283 }
2284 }
2285
Douglas Gregora030b7c2010-01-22 20:35:53 +00002286 CIndexer *CIdxr = new CIndexer();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002287 if (excludeDeclarationsFromPCH)
2288 CIdxr->setOnlyLocalDecls();
Douglas Gregor0a812cf2010-02-18 23:07:20 +00002289 if (displayDiagnostics)
2290 CIdxr->setDisplayDiagnostics();
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002291 return CIdxr;
Steve Naroff600866c2009-08-27 19:51:58 +00002292}
2293
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002294void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002295 if (CIdx)
2296 delete static_cast<CIndexer *>(CIdx);
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002297}
2298
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002299CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregora88084b2010-02-18 18:08:43 +00002300 const char *ast_filename) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002301 if (!CIdx)
2302 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002303
Douglas Gregor7d1d49d2009-10-16 20:01:17 +00002304 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis389db162010-11-03 22:45:23 +00002305 FileSystemOptions FileSystemOpts;
2306 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002307
Douglas Gregor28019772010-04-05 23:52:57 +00002308 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremeneka60ed472010-11-16 08:15:36 +00002309 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregora88084b2010-02-18 18:08:43 +00002310 CXXIdx->getOnlyLocalDecls(),
2311 0, 0, true);
Ted Kremeneka60ed472010-11-16 08:15:36 +00002312 return MakeCXTranslationUnit(TU);
Steve Naroff600866c2009-08-27 19:51:58 +00002313}
2314
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002315unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor2a2c50b2010-09-27 05:49:58 +00002316 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregor99ba2022010-10-27 17:24:53 +00002317 CXTranslationUnit_CacheCompletionResults |
2318 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregorb1c031b2010-08-09 22:28:58 +00002319}
2320
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002321CXTranslationUnit
2322clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2323 const char *source_filename,
2324 int num_command_line_args,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002325 const char * const *command_line_args,
Douglas Gregor4db64a42010-01-23 00:14:00 +00002326 unsigned num_unsaved_files,
Douglas Gregora88084b2010-02-18 18:08:43 +00002327 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor5a430212010-07-21 18:52:53 +00002328 return clang_parseTranslationUnit(CIdx, source_filename,
2329 command_line_args, num_command_line_args,
2330 unsaved_files, num_unsaved_files,
2331 CXTranslationUnit_DetailedPreprocessingRecord);
2332}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002333
2334struct ParseTranslationUnitInfo {
2335 CXIndex CIdx;
2336 const char *source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002337 const char *const *command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002338 int num_command_line_args;
2339 struct CXUnsavedFile *unsaved_files;
2340 unsigned num_unsaved_files;
2341 unsigned options;
2342 CXTranslationUnit result;
2343};
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002344static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002345 ParseTranslationUnitInfo *PTUI =
2346 static_cast<ParseTranslationUnitInfo*>(UserData);
2347 CXIndex CIdx = PTUI->CIdx;
2348 const char *source_filename = PTUI->source_filename;
Douglas Gregor2ef69442010-09-01 16:43:19 +00002349 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002350 int num_command_line_args = PTUI->num_command_line_args;
2351 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2352 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2353 unsigned options = PTUI->options;
2354 PTUI->result = 0;
Douglas Gregor5a430212010-07-21 18:52:53 +00002355
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002356 if (!CIdx)
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002357 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002358
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002359 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2360
Douglas Gregor44c181a2010-07-23 00:33:23 +00002361 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregordf95a132010-08-09 20:45:32 +00002362 bool CompleteTranslationUnit
2363 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregor87c08a52010-08-13 22:48:40 +00002364 bool CacheCodeCompetionResults
2365 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregor99ba2022010-10-27 17:24:53 +00002366 bool CXXPrecompilePreamble
2367 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2368 bool CXXChainedPCH
2369 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregor87c08a52010-08-13 22:48:40 +00002370
Douglas Gregor5352ac02010-01-28 00:27:43 +00002371 // Configure the diagnostics.
2372 DiagnosticOptions DiagOpts;
Douglas Gregor28019772010-04-05 23:52:57 +00002373 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Douglas Gregor0b53cf82011-01-19 01:02:47 +00002374 Diags = CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2375 command_line_args);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002376
Douglas Gregor4db64a42010-01-23 00:14:00 +00002377 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2378 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattnera0a270c2010-04-05 22:42:27 +00002379 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002380 const llvm::MemoryBuffer *Buffer
Chris Lattnera0a270c2010-04-05 22:42:27 +00002381 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregor4db64a42010-01-23 00:14:00 +00002382 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2383 Buffer));
2384 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002385
Douglas Gregorb10daed2010-10-11 16:52:23 +00002386 llvm::SmallVector<const char *, 16> Args;
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002387
Ted Kremenek139ba862009-10-22 00:03:57 +00002388 // The 'source_filename' argument is optional. If the caller does not
2389 // specify it then it is assumed that the source file is specified
2390 // in the actual argument list.
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002391 if (source_filename)
Douglas Gregorb10daed2010-10-11 16:52:23 +00002392 Args.push_back(source_filename);
Douglas Gregor52ddc5d2010-07-09 18:39:07 +00002393
2394 // Since the Clang C library is primarily used by batch tools dealing with
2395 // (often very broken) source code, where spell-checking can have a
2396 // significant negative impact on performance (particularly when
2397 // precompiled headers are involved), we disable it by default.
Douglas Gregorb10daed2010-10-11 16:52:23 +00002398 // Only do this if we haven't found a spell-checking-related argument.
2399 bool FoundSpellCheckingArgument = false;
2400 for (int I = 0; I != num_command_line_args; ++I) {
2401 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2402 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2403 FoundSpellCheckingArgument = true;
2404 break;
Steve Naroffe56b4ba2009-10-20 14:46:24 +00002405 }
Douglas Gregorb10daed2010-10-11 16:52:23 +00002406 }
2407 if (!FoundSpellCheckingArgument)
2408 Args.push_back("-fno-spell-checking");
2409
2410 Args.insert(Args.end(), command_line_args,
2411 command_line_args + num_command_line_args);
Douglas Gregord93256e2010-01-28 06:00:51 +00002412
Douglas Gregor44c181a2010-07-23 00:33:23 +00002413 // Do we need the detailed preprocessing record?
2414 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002415 Args.push_back("-Xclang");
2416 Args.push_back("-detailed-preprocessing-record");
Douglas Gregor44c181a2010-07-23 00:33:23 +00002417 }
2418
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002419 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregorb10daed2010-10-11 16:52:23 +00002420 llvm::OwningPtr<ASTUnit> Unit(
2421 ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
2422 Diags,
2423 CXXIdx->getClangResourcesPath(),
2424 CXXIdx->getOnlyLocalDecls(),
Douglas Gregore47be3e2010-11-11 00:39:14 +00002425 /*CaptureDiagnostics=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002426 RemappedFiles.data(),
2427 RemappedFiles.size(),
Argyrios Kyrtzidis299a4a92011-03-08 23:35:24 +00002428 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregorb10daed2010-10-11 16:52:23 +00002429 PrecompilePreamble,
2430 CompleteTranslationUnit,
Douglas Gregor99ba2022010-10-27 17:24:53 +00002431 CacheCodeCompetionResults,
2432 CXXPrecompilePreamble,
2433 CXXChainedPCH));
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002434
Argyrios Kyrtzidis026f6912010-11-18 21:47:04 +00002435 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregorb10daed2010-10-11 16:52:23 +00002436 // Make sure to check that 'Unit' is non-NULL.
2437 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2438 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2439 DEnd = Unit->stored_diag_end();
2440 D != DEnd; ++D) {
2441 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2442 CXString Msg = clang_formatDiagnostic(&Diag,
2443 clang_defaultDiagnosticDisplayOptions());
2444 fprintf(stderr, "%s\n", clang_getCString(Msg));
2445 clang_disposeString(Msg);
2446 }
Douglas Gregor274f1902010-02-22 23:17:23 +00002447#ifdef LLVM_ON_WIN32
Douglas Gregorb10daed2010-10-11 16:52:23 +00002448 // On Windows, force a flush, since there may be multiple copies of
2449 // stderr and stdout in the file system, all with different buffers
2450 // but writing to the same device.
2451 fflush(stderr);
2452#endif
2453 }
Douglas Gregora88084b2010-02-18 18:08:43 +00002454 }
Douglas Gregord93256e2010-01-28 06:00:51 +00002455
Ted Kremeneka60ed472010-11-16 08:15:36 +00002456 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002457}
2458CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2459 const char *source_filename,
Douglas Gregor2ef69442010-09-01 16:43:19 +00002460 const char * const *command_line_args,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002461 int num_command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002462 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002463 unsigned num_unsaved_files,
2464 unsigned options) {
2465 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002466 num_command_line_args, unsaved_files,
2467 num_unsaved_files, options, 0 };
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002468 llvm::CrashRecoveryContext CRC;
2469
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002470 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbar60a45432010-08-23 22:35:34 +00002471 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2472 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2473 fprintf(stderr, " 'command_line_args' : [");
2474 for (int i = 0; i != num_command_line_args; ++i) {
2475 if (i)
2476 fprintf(stderr, ", ");
2477 fprintf(stderr, "'%s'", command_line_args[i]);
2478 }
2479 fprintf(stderr, "],\n");
2480 fprintf(stderr, " 'unsaved_files' : [");
2481 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2482 if (i)
2483 fprintf(stderr, ", ");
2484 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2485 unsaved_files[i].Length);
2486 }
2487 fprintf(stderr, "],\n");
2488 fprintf(stderr, " 'options' : %d,\n", options);
2489 fprintf(stderr, "}\n");
2490
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002491 return 0;
2492 }
2493
2494 return PTUI.result;
Steve Naroff5b7d8e22009-10-15 20:04:39 +00002495}
2496
Douglas Gregor19998442010-08-13 15:35:05 +00002497unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2498 return CXSaveTranslationUnit_None;
2499}
2500
2501int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2502 unsigned options) {
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002503 if (!TU)
2504 return 1;
2505
Ted Kremeneka60ed472010-11-16 08:15:36 +00002506 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregor7ae2faa2010-08-13 05:36:37 +00002507}
Daniel Dunbar19ffd492010-08-18 18:43:17 +00002508
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002509void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002510 if (CTUnit) {
2511 // If the translation unit has been marked as unsafe to free, just discard
2512 // it.
Ted Kremeneka60ed472010-11-16 08:15:36 +00002513 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002514 return;
2515
Ted Kremeneka60ed472010-11-16 08:15:36 +00002516 delete static_cast<ASTUnit *>(CTUnit->TUData);
2517 disposeCXStringPool(CTUnit->StringPool);
2518 delete CTUnit;
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002519 }
Steve Naroff2bd6b9f2009-09-17 18:33:27 +00002520}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00002521
Douglas Gregore1e13bf2010-08-11 15:58:42 +00002522unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2523 return CXReparse_None;
2524}
2525
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002526struct ReparseTranslationUnitInfo {
2527 CXTranslationUnit TU;
2528 unsigned num_unsaved_files;
2529 struct CXUnsavedFile *unsaved_files;
2530 unsigned options;
2531 int result;
2532};
Douglas Gregor593b0c12010-09-23 18:47:53 +00002533
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002534static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002535 ReparseTranslationUnitInfo *RTUI =
2536 static_cast<ReparseTranslationUnitInfo*>(UserData);
2537 CXTranslationUnit TU = RTUI->TU;
2538 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2539 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2540 unsigned options = RTUI->options;
2541 (void) options;
2542 RTUI->result = 1;
2543
Douglas Gregorabc563f2010-07-19 21:46:24 +00002544 if (!TU)
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002545 return;
Douglas Gregor593b0c12010-09-23 18:47:53 +00002546
Ted Kremeneka60ed472010-11-16 08:15:36 +00002547 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor593b0c12010-09-23 18:47:53 +00002548 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002549
2550 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2551 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2552 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2553 const llvm::MemoryBuffer *Buffer
Douglas Gregor1abc6bc2010-08-04 16:47:14 +00002554 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregorabc563f2010-07-19 21:46:24 +00002555 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2556 Buffer));
2557 }
2558
Douglas Gregor593b0c12010-09-23 18:47:53 +00002559 if (!CXXUnit->Reparse(RemappedFiles.data(), RemappedFiles.size()))
2560 RTUI->result = 0;
Douglas Gregorabc563f2010-07-19 21:46:24 +00002561}
Douglas Gregor593b0c12010-09-23 18:47:53 +00002562
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002563int clang_reparseTranslationUnit(CXTranslationUnit TU,
2564 unsigned num_unsaved_files,
2565 struct CXUnsavedFile *unsaved_files,
2566 unsigned options) {
2567 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2568 options, 0 };
2569 llvm::CrashRecoveryContext CRC;
2570
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00002571 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbarb1fd3452010-08-19 23:44:10 +00002572 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002573 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002574 return 1;
2575 }
2576
Ted Kremenek1dfb26a2010-10-29 01:06:50 +00002577
Daniel Dunbarea94bbc2010-08-18 23:09:31 +00002578 return RTUI.result;
2579}
2580
Douglas Gregordf95a132010-08-09 20:45:32 +00002581
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002582CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor2b37c9e2010-01-29 00:47:48 +00002583 if (!CTUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002584 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002585
Ted Kremeneka60ed472010-11-16 08:15:36 +00002586 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002587 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroffaf08ddc2009-09-03 15:49:00 +00002588}
Daniel Dunbar1eb79b52009-08-28 16:30:07 +00002589
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002590CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00002591 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002592 return Result;
2593}
2594
Ted Kremenekfb480492010-01-13 21:46:36 +00002595} // end: extern "C"
Steve Naroff600866c2009-08-27 19:51:58 +00002596
Ted Kremenekfb480492010-01-13 21:46:36 +00002597//===----------------------------------------------------------------------===//
Douglas Gregor1db19de2010-01-19 21:36:55 +00002598// CXSourceLocation and CXSourceRange Operations.
2599//===----------------------------------------------------------------------===//
2600
Douglas Gregorb9790342010-01-22 21:44:22 +00002601extern "C" {
2602CXSourceLocation clang_getNullLocation() {
Douglas Gregor5352ac02010-01-28 00:27:43 +00002603 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregorb9790342010-01-22 21:44:22 +00002604 return Result;
2605}
2606
2607unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar90a6b9e2010-01-30 23:58:27 +00002608 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2609 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2610 loc1.int_data == loc2.int_data);
Douglas Gregorb9790342010-01-22 21:44:22 +00002611}
2612
2613CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2614 CXFile file,
2615 unsigned line,
2616 unsigned column) {
Douglas Gregor42748ec2010-04-30 19:45:53 +00002617 if (!tu || !file)
Douglas Gregorb9790342010-01-22 21:44:22 +00002618 return clang_getNullLocation();
Douglas Gregor42748ec2010-04-30 19:45:53 +00002619
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002620 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremeneka60ed472010-11-16 08:15:36 +00002621 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002622 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregorb9790342010-01-22 21:44:22 +00002623 SourceLocation SLoc
Douglas Gregor86a4d0d2011-02-03 17:17:35 +00002624 = CXXUnit->getSourceManager().getLocation(File, line, column);
2625 if (SLoc.isInvalid()) {
2626 if (Logging)
2627 llvm::errs() << "clang_getLocation(\"" << File->getName()
2628 << "\", " << line << ", " << column << ") = invalid\n";
2629 return clang_getNullLocation();
2630 }
2631
2632 if (Logging)
2633 llvm::errs() << "clang_getLocation(\"" << File->getName()
2634 << "\", " << line << ", " << column << ") = "
2635 << SLoc.getRawEncoding() << "\n";
David Chisnall83889a72010-10-15 17:07:39 +00002636
2637 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2638}
2639
2640CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2641 CXFile file,
2642 unsigned offset) {
2643 if (!tu || !file)
2644 return clang_getNullLocation();
2645
Ted Kremeneka60ed472010-11-16 08:15:36 +00002646 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall83889a72010-10-15 17:07:39 +00002647 SourceLocation Start
2648 = CXXUnit->getSourceManager().getLocation(
2649 static_cast<const FileEntry *>(file),
2650 1, 1);
2651 if (Start.isInvalid()) return clang_getNullLocation();
2652
2653 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2654
2655 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002656
Ted Kremenek1a9a0bc2010-06-28 23:54:17 +00002657 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregorb9790342010-01-22 21:44:22 +00002658}
2659
Douglas Gregor5352ac02010-01-28 00:27:43 +00002660CXSourceRange clang_getNullRange() {
2661 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2662 return Result;
2663}
Daniel Dunbard52864b2010-02-14 10:02:57 +00002664
Douglas Gregor5352ac02010-01-28 00:27:43 +00002665CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2666 if (begin.ptr_data[0] != end.ptr_data[0] ||
2667 begin.ptr_data[1] != end.ptr_data[1])
2668 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002669
2670 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002671 begin.int_data, end.int_data };
Douglas Gregorb9790342010-01-22 21:44:22 +00002672 return Result;
2673}
2674
Douglas Gregor46766dc2010-01-26 19:19:08 +00002675void clang_getInstantiationLocation(CXSourceLocation location,
2676 CXFile *file,
2677 unsigned *line,
2678 unsigned *column,
2679 unsigned *offset) {
Douglas Gregor1db19de2010-01-19 21:36:55 +00002680 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2681
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002682 if (!location.ptr_data[0] || Loc.isInvalid()) {
Douglas Gregor46766dc2010-01-26 19:19:08 +00002683 if (file)
2684 *file = 0;
2685 if (line)
2686 *line = 0;
2687 if (column)
2688 *column = 0;
2689 if (offset)
2690 *offset = 0;
2691 return;
2692 }
2693
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002694 const SourceManager &SM =
2695 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002696 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor1db19de2010-01-19 21:36:55 +00002697
2698 if (file)
2699 *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));
2700 if (line)
2701 *line = SM.getInstantiationLineNumber(InstLoc);
2702 if (column)
2703 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregore69517c2010-01-26 03:07:15 +00002704 if (offset)
Douglas Gregor46766dc2010-01-26 19:19:08 +00002705 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregore69517c2010-01-26 03:07:15 +00002706}
2707
Douglas Gregora9b06d42010-11-09 06:24:54 +00002708void clang_getSpellingLocation(CXSourceLocation location,
2709 CXFile *file,
2710 unsigned *line,
2711 unsigned *column,
2712 unsigned *offset) {
2713 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2714
2715 if (!location.ptr_data[0] || Loc.isInvalid()) {
2716 if (file)
2717 *file = 0;
2718 if (line)
2719 *line = 0;
2720 if (column)
2721 *column = 0;
2722 if (offset)
2723 *offset = 0;
2724 return;
2725 }
2726
2727 const SourceManager &SM =
2728 *static_cast<const SourceManager*>(location.ptr_data[0]);
2729 SourceLocation SpellLoc = Loc;
2730 if (SpellLoc.isMacroID()) {
2731 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2732 if (SimpleSpellingLoc.isFileID() &&
2733 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2734 SpellLoc = SimpleSpellingLoc;
2735 else
2736 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2737 }
2738
2739 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2740 FileID FID = LocInfo.first;
2741 unsigned FileOffset = LocInfo.second;
2742
2743 if (file)
2744 *file = (void *)SM.getFileEntryForID(FID);
2745 if (line)
2746 *line = SM.getLineNumber(FID, FileOffset);
2747 if (column)
2748 *column = SM.getColumnNumber(FID, FileOffset);
2749 if (offset)
2750 *offset = FileOffset;
2751}
2752
Douglas Gregor1db19de2010-01-19 21:36:55 +00002753CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002754 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002755 range.begin_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002756 return Result;
2757}
2758
2759CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarbb4a61a2010-02-14 01:47:36 +00002760 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor5352ac02010-01-28 00:27:43 +00002761 range.end_int_data };
Douglas Gregor1db19de2010-01-19 21:36:55 +00002762 return Result;
2763}
2764
Douglas Gregorb9790342010-01-22 21:44:22 +00002765} // end: extern "C"
2766
Douglas Gregor1db19de2010-01-19 21:36:55 +00002767//===----------------------------------------------------------------------===//
Ted Kremenekfb480492010-01-13 21:46:36 +00002768// CXFile Operations.
2769//===----------------------------------------------------------------------===//
2770
2771extern "C" {
Ted Kremenek74844072010-02-17 00:41:20 +00002772CXString clang_getFileName(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002773 if (!SFile)
Ted Kremeneka60ed472010-11-16 08:15:36 +00002774 return createCXString((const char*)NULL);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002775
Steve Naroff88145032009-10-27 14:35:18 +00002776 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenek74844072010-02-17 00:41:20 +00002777 return createCXString(FEnt->getName());
Steve Naroff88145032009-10-27 14:35:18 +00002778}
2779
2780time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor98258af2010-01-18 22:46:11 +00002781 if (!SFile)
2782 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002783
Steve Naroff88145032009-10-27 14:35:18 +00002784 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2785 return FEnt->getModificationTime();
Steve Naroffee9405e2009-09-25 21:45:39 +00002786}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002787
Douglas Gregorb9790342010-01-22 21:44:22 +00002788CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2789 if (!tu)
2790 return 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002791
Ted Kremeneka60ed472010-11-16 08:15:36 +00002792 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002793
Douglas Gregorb9790342010-01-22 21:44:22 +00002794 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner39b49bc2010-11-23 08:35:12 +00002795 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregorb9790342010-01-22 21:44:22 +00002796}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002797
Ted Kremenekfb480492010-01-13 21:46:36 +00002798} // end: extern "C"
Steve Naroffee9405e2009-09-25 21:45:39 +00002799
Ted Kremenekfb480492010-01-13 21:46:36 +00002800//===----------------------------------------------------------------------===//
2801// CXCursor Operations.
2802//===----------------------------------------------------------------------===//
2803
Ted Kremenekfb480492010-01-13 21:46:36 +00002804static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregordb1314e2010-10-01 21:11:22 +00002805 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2806 return getDeclFromExpr(CE->getSubExpr());
2807
Ted Kremenekfb480492010-01-13 21:46:36 +00002808 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2809 return RefExpr->getDecl();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002810 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2811 return RefExpr->getDecl();
Ted Kremenekfb480492010-01-13 21:46:36 +00002812 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2813 return ME->getMemberDecl();
2814 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2815 return RE->getDecl();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002816 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCall12f78a62010-12-02 01:19:52 +00002817 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregordb1314e2010-10-01 21:11:22 +00002818
Ted Kremenekfb480492010-01-13 21:46:36 +00002819 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2820 return getDeclFromExpr(CE->getCallee());
Douglas Gregor93798e22010-11-05 21:11:19 +00002821 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2822 if (!CE->isElidable())
2823 return CE->getConstructor();
Ted Kremenekfb480492010-01-13 21:46:36 +00002824 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2825 return OME->getMethodDecl();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002826
Douglas Gregordb1314e2010-10-01 21:11:22 +00002827 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2828 return PE->getProtocol();
Douglas Gregorc7793c72011-01-15 01:15:58 +00002829 if (SubstNonTypeTemplateParmPackExpr *NTTP
2830 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2831 return NTTP->getParameterPack();
Douglas Gregor94d96292011-01-19 20:34:17 +00002832 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2833 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2834 isa<ParmVarDecl>(SizeOfPack->getPack()))
2835 return SizeOfPack->getPack();
Douglas Gregordb1314e2010-10-01 21:11:22 +00002836
Ted Kremenekfb480492010-01-13 21:46:36 +00002837 return 0;
2838}
2839
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002840static SourceLocation getLocationFromExpr(Expr *E) {
2841 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2842 return /*FIXME:*/Msg->getLeftLoc();
2843 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2844 return DRE->getLocation();
Douglas Gregor38f28c12010-10-22 22:24:08 +00002845 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2846 return RefExpr->getLocation();
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002847 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2848 return Member->getMemberLoc();
2849 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2850 return Ivar->getLocation();
Douglas Gregor94d96292011-01-19 20:34:17 +00002851 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2852 return SizeOfPack->getPackLoc();
2853
Daniel Dunbarc29f4c32010-02-02 05:00:22 +00002854 return E->getLocStart();
2855}
2856
Ted Kremenekfb480492010-01-13 21:46:36 +00002857extern "C" {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002858
2859unsigned clang_visitChildren(CXCursor parent,
Douglas Gregorb1373d02010-01-20 20:59:29 +00002860 CXCursorVisitor visitor,
2861 CXClientData client_data) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00002862 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
2863 getCursorASTUnit(parent)->getMaxPCHLevel());
Douglas Gregorb1373d02010-01-20 20:59:29 +00002864 return CursorVis.VisitChildren(parent);
2865}
2866
David Chisnall3387c652010-11-03 14:12:26 +00002867#ifndef __has_feature
2868#define __has_feature(x) 0
2869#endif
2870#if __has_feature(blocks)
2871typedef enum CXChildVisitResult
2872 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2873
2874static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2875 CXClientData client_data) {
2876 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2877 return block(cursor, parent);
2878}
2879#else
2880// If we are compiled with a compiler that doesn't have native blocks support,
2881// define and call the block manually, so the
2882typedef struct _CXChildVisitResult
2883{
2884 void *isa;
2885 int flags;
2886 int reserved;
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002887 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2888 CXCursor);
David Chisnall3387c652010-11-03 14:12:26 +00002889} *CXCursorVisitorBlock;
2890
2891static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2892 CXClientData client_data) {
2893 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2894 return block->invoke(block, cursor, parent);
2895}
2896#endif
2897
2898
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00002899unsigned clang_visitChildrenWithBlock(CXCursor parent,
2900 CXCursorVisitorBlock block) {
David Chisnall3387c652010-11-03 14:12:26 +00002901 return clang_visitChildren(parent, visitWithBlock, block);
2902}
2903
Douglas Gregor78205d42010-01-20 21:45:58 +00002904static CXString getDeclSpelling(Decl *D) {
2905 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregore3c60a72010-11-17 00:13:31 +00002906 if (!ND) {
2907 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2908 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2909 return createCXString(Property->getIdentifier()->getName());
2910
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002911 return createCXString("");
Douglas Gregore3c60a72010-11-17 00:13:31 +00002912 }
2913
Douglas Gregor78205d42010-01-20 21:45:58 +00002914 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002915 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002916
Douglas Gregor78205d42010-01-20 21:45:58 +00002917 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2918 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2919 // and returns different names. NamedDecl returns the class name and
2920 // ObjCCategoryImplDecl returns the category name.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002921 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002922
Douglas Gregor0a35bce2010-09-01 03:07:18 +00002923 if (isa<UsingDirectiveDecl>(D))
2924 return createCXString("");
2925
Ted Kremenek50aa6ac2010-05-19 21:51:10 +00002926 llvm::SmallString<1024> S;
2927 llvm::raw_svector_ostream os(S);
2928 ND->printName(os);
2929
2930 return createCXString(os.str());
Douglas Gregor78205d42010-01-20 21:45:58 +00002931}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00002932
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00002933CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002934 if (clang_isTranslationUnit(C.kind))
Ted Kremeneka60ed472010-11-16 08:15:36 +00002935 return clang_getTranslationUnitSpelling(
2936 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00002937
Steve Narofff334b4e2009-09-02 18:26:48 +00002938 if (clang_isReference(C.kind)) {
2939 switch (C.kind) {
Daniel Dunbaracca7252009-11-30 20:42:49 +00002940 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor2e331b92010-01-16 14:00:32 +00002941 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002942 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002943 }
2944 case CXCursor_ObjCClassRef: {
Douglas Gregor1adb0822010-01-16 17:14:40 +00002945 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002946 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002947 }
2948 case CXCursor_ObjCProtocolRef: {
Douglas Gregor78db0cd2010-01-16 15:44:18 +00002949 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregorf46034a2010-01-18 23:41:10 +00002950 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002951 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbaracca7252009-11-30 20:42:49 +00002952 }
Ted Kremenek3064ef92010-08-27 21:34:58 +00002953 case CXCursor_CXXBaseSpecifier: {
2954 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
2955 return createCXString(B->getType().getAsString());
2956 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002957 case CXCursor_TypeRef: {
2958 TypeDecl *Type = getCursorTypeRef(C).first;
2959 assert(Type && "Missing type decl");
2960
Ted Kremenekee4db4f2010-02-17 00:41:08 +00002961 return createCXString(getCursorContext(C).getTypeDeclType(Type).
2962 getAsString());
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002963 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00002964 case CXCursor_TemplateRef: {
2965 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregor69319002010-08-31 23:48:11 +00002966 assert(Template && "Missing template decl");
Douglas Gregor0b36e612010-08-31 20:37:03 +00002967
2968 return createCXString(Template->getNameAsString());
2969 }
Douglas Gregor69319002010-08-31 23:48:11 +00002970
2971 case CXCursor_NamespaceRef: {
2972 NamedDecl *NS = getCursorNamespaceRef(C).first;
2973 assert(NS && "Missing namespace decl");
2974
2975 return createCXString(NS->getNameAsString());
2976 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00002977
Douglas Gregora67e03f2010-09-09 21:42:20 +00002978 case CXCursor_MemberRef: {
2979 FieldDecl *Field = getCursorMemberRef(C).first;
2980 assert(Field && "Missing member decl");
2981
2982 return createCXString(Field->getNameAsString());
2983 }
2984
Douglas Gregor36897b02010-09-10 00:22:18 +00002985 case CXCursor_LabelRef: {
2986 LabelStmt *Label = getCursorLabelRef(C).first;
2987 assert(Label && "Missing label");
2988
Chris Lattnerad8dcf42011-02-17 07:39:24 +00002989 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00002990 }
2991
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00002992 case CXCursor_OverloadedDeclRef: {
2993 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
2994 if (Decl *D = Storage.dyn_cast<Decl *>()) {
2995 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
2996 return createCXString(ND->getNameAsString());
2997 return createCXString("");
2998 }
2999 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3000 return createCXString(E->getName().getAsString());
3001 OverloadedTemplateStorage *Ovl
3002 = Storage.get<OverloadedTemplateStorage*>();
3003 if (Ovl->size() == 0)
3004 return createCXString("");
3005 return createCXString((*Ovl->begin())->getNameAsString());
3006 }
3007
Daniel Dunbaracca7252009-11-30 20:42:49 +00003008 default:
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003009 return createCXString("<not implemented>");
Steve Narofff334b4e2009-09-02 18:26:48 +00003010 }
3011 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003012
3013 if (clang_isExpression(C.kind)) {
3014 Decl *D = getDeclFromExpr(getCursorExpr(C));
3015 if (D)
Douglas Gregor78205d42010-01-20 21:45:58 +00003016 return getDeclSpelling(D);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003017 return createCXString("");
Douglas Gregor97b98722010-01-19 23:20:36 +00003018 }
3019
Douglas Gregor36897b02010-09-10 00:22:18 +00003020 if (clang_isStatement(C.kind)) {
3021 Stmt *S = getCursorStmt(C);
3022 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003023 return createCXString(Label->getName());
Douglas Gregor36897b02010-09-10 00:22:18 +00003024
3025 return createCXString("");
3026 }
3027
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003028 if (C.kind == CXCursor_MacroInstantiation)
3029 return createCXString(getCursorMacroInstantiation(C)->getName()
3030 ->getNameStart());
3031
Douglas Gregor572feb22010-03-18 18:04:21 +00003032 if (C.kind == CXCursor_MacroDefinition)
3033 return createCXString(getCursorMacroDefinition(C)->getName()
3034 ->getNameStart());
3035
Douglas Gregorecdcb882010-10-20 22:00:55 +00003036 if (C.kind == CXCursor_InclusionDirective)
3037 return createCXString(getCursorInclusionDirective(C)->getFileName());
3038
Douglas Gregor60cbfac2010-01-25 16:56:17 +00003039 if (clang_isDeclaration(C.kind))
3040 return getDeclSpelling(getCursorDecl(C));
Ted Kremeneke68fff62010-02-17 00:41:32 +00003041
Ted Kremenekee4db4f2010-02-17 00:41:08 +00003042 return createCXString("");
Steve Narofff334b4e2009-09-02 18:26:48 +00003043}
3044
Douglas Gregor358559d2010-10-02 22:49:11 +00003045CXString clang_getCursorDisplayName(CXCursor C) {
3046 if (!clang_isDeclaration(C.kind))
3047 return clang_getCursorSpelling(C);
3048
3049 Decl *D = getCursorDecl(C);
3050 if (!D)
3051 return createCXString("");
3052
3053 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3054 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3055 D = FunTmpl->getTemplatedDecl();
3056
3057 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3058 llvm::SmallString<64> Str;
3059 llvm::raw_svector_ostream OS(Str);
3060 OS << Function->getNameAsString();
3061 if (Function->getPrimaryTemplate())
3062 OS << "<>";
3063 OS << "(";
3064 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3065 if (I)
3066 OS << ", ";
3067 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3068 }
3069
3070 if (Function->isVariadic()) {
3071 if (Function->getNumParams())
3072 OS << ", ";
3073 OS << "...";
3074 }
3075 OS << ")";
3076 return createCXString(OS.str());
3077 }
3078
3079 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3080 llvm::SmallString<64> Str;
3081 llvm::raw_svector_ostream OS(Str);
3082 OS << ClassTemplate->getNameAsString();
3083 OS << "<";
3084 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3085 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3086 if (I)
3087 OS << ", ";
3088
3089 NamedDecl *Param = Params->getParam(I);
3090 if (Param->getIdentifier()) {
3091 OS << Param->getIdentifier()->getName();
3092 continue;
3093 }
3094
3095 // There is no parameter name, which makes this tricky. Try to come up
3096 // with something useful that isn't too long.
3097 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3098 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3099 else if (NonTypeTemplateParmDecl *NTTP
3100 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3101 OS << NTTP->getType().getAsString(Policy);
3102 else
3103 OS << "template<...> class";
3104 }
3105
3106 OS << ">";
3107 return createCXString(OS.str());
3108 }
3109
3110 if (ClassTemplateSpecializationDecl *ClassSpec
3111 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3112 // If the type was explicitly written, use that.
3113 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3114 return createCXString(TSInfo->getType().getAsString(Policy));
3115
3116 llvm::SmallString<64> Str;
3117 llvm::raw_svector_ostream OS(Str);
3118 OS << ClassSpec->getNameAsString();
3119 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor910f8002010-11-07 23:05:16 +00003120 ClassSpec->getTemplateArgs().data(),
3121 ClassSpec->getTemplateArgs().size(),
Douglas Gregor358559d2010-10-02 22:49:11 +00003122 Policy);
3123 return createCXString(OS.str());
3124 }
3125
3126 return clang_getCursorSpelling(C);
3127}
3128
Ted Kremeneke68fff62010-02-17 00:41:32 +00003129CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff89922f82009-08-31 00:59:03 +00003130 switch (Kind) {
Ted Kremeneke68fff62010-02-17 00:41:32 +00003131 case CXCursor_FunctionDecl:
3132 return createCXString("FunctionDecl");
3133 case CXCursor_TypedefDecl:
3134 return createCXString("TypedefDecl");
3135 case CXCursor_EnumDecl:
3136 return createCXString("EnumDecl");
3137 case CXCursor_EnumConstantDecl:
3138 return createCXString("EnumConstantDecl");
3139 case CXCursor_StructDecl:
3140 return createCXString("StructDecl");
3141 case CXCursor_UnionDecl:
3142 return createCXString("UnionDecl");
3143 case CXCursor_ClassDecl:
3144 return createCXString("ClassDecl");
3145 case CXCursor_FieldDecl:
3146 return createCXString("FieldDecl");
3147 case CXCursor_VarDecl:
3148 return createCXString("VarDecl");
3149 case CXCursor_ParmDecl:
3150 return createCXString("ParmDecl");
3151 case CXCursor_ObjCInterfaceDecl:
3152 return createCXString("ObjCInterfaceDecl");
3153 case CXCursor_ObjCCategoryDecl:
3154 return createCXString("ObjCCategoryDecl");
3155 case CXCursor_ObjCProtocolDecl:
3156 return createCXString("ObjCProtocolDecl");
3157 case CXCursor_ObjCPropertyDecl:
3158 return createCXString("ObjCPropertyDecl");
3159 case CXCursor_ObjCIvarDecl:
3160 return createCXString("ObjCIvarDecl");
3161 case CXCursor_ObjCInstanceMethodDecl:
3162 return createCXString("ObjCInstanceMethodDecl");
3163 case CXCursor_ObjCClassMethodDecl:
3164 return createCXString("ObjCClassMethodDecl");
3165 case CXCursor_ObjCImplementationDecl:
3166 return createCXString("ObjCImplementationDecl");
3167 case CXCursor_ObjCCategoryImplDecl:
3168 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek8bd5a692010-04-13 23:39:06 +00003169 case CXCursor_CXXMethod:
3170 return createCXString("CXXMethod");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003171 case CXCursor_UnexposedDecl:
3172 return createCXString("UnexposedDecl");
3173 case CXCursor_ObjCSuperClassRef:
3174 return createCXString("ObjCSuperClassRef");
3175 case CXCursor_ObjCProtocolRef:
3176 return createCXString("ObjCProtocolRef");
3177 case CXCursor_ObjCClassRef:
3178 return createCXString("ObjCClassRef");
3179 case CXCursor_TypeRef:
3180 return createCXString("TypeRef");
Douglas Gregor0b36e612010-08-31 20:37:03 +00003181 case CXCursor_TemplateRef:
3182 return createCXString("TemplateRef");
Douglas Gregor69319002010-08-31 23:48:11 +00003183 case CXCursor_NamespaceRef:
3184 return createCXString("NamespaceRef");
Douglas Gregora67e03f2010-09-09 21:42:20 +00003185 case CXCursor_MemberRef:
3186 return createCXString("MemberRef");
Douglas Gregor36897b02010-09-10 00:22:18 +00003187 case CXCursor_LabelRef:
3188 return createCXString("LabelRef");
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003189 case CXCursor_OverloadedDeclRef:
3190 return createCXString("OverloadedDeclRef");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003191 case CXCursor_UnexposedExpr:
3192 return createCXString("UnexposedExpr");
Ted Kremenek1ee6cad2010-04-11 21:47:37 +00003193 case CXCursor_BlockExpr:
3194 return createCXString("BlockExpr");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003195 case CXCursor_DeclRefExpr:
3196 return createCXString("DeclRefExpr");
3197 case CXCursor_MemberRefExpr:
3198 return createCXString("MemberRefExpr");
3199 case CXCursor_CallExpr:
3200 return createCXString("CallExpr");
3201 case CXCursor_ObjCMessageExpr:
3202 return createCXString("ObjCMessageExpr");
3203 case CXCursor_UnexposedStmt:
3204 return createCXString("UnexposedStmt");
Douglas Gregor36897b02010-09-10 00:22:18 +00003205 case CXCursor_LabelStmt:
3206 return createCXString("LabelStmt");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003207 case CXCursor_InvalidFile:
3208 return createCXString("InvalidFile");
Ted Kremenek292db642010-03-19 20:39:05 +00003209 case CXCursor_InvalidCode:
3210 return createCXString("InvalidCode");
Ted Kremeneke68fff62010-02-17 00:41:32 +00003211 case CXCursor_NoDeclFound:
3212 return createCXString("NoDeclFound");
3213 case CXCursor_NotImplemented:
3214 return createCXString("NotImplemented");
3215 case CXCursor_TranslationUnit:
3216 return createCXString("TranslationUnit");
Ted Kremeneke77f4432010-02-18 03:09:07 +00003217 case CXCursor_UnexposedAttr:
3218 return createCXString("UnexposedAttr");
3219 case CXCursor_IBActionAttr:
3220 return createCXString("attribute(ibaction)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003221 case CXCursor_IBOutletAttr:
3222 return createCXString("attribute(iboutlet)");
Ted Kremenek857e9182010-05-19 17:38:06 +00003223 case CXCursor_IBOutletCollectionAttr:
3224 return createCXString("attribute(iboutletcollection)");
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003225 case CXCursor_PreprocessingDirective:
3226 return createCXString("preprocessing directive");
Douglas Gregor572feb22010-03-18 18:04:21 +00003227 case CXCursor_MacroDefinition:
3228 return createCXString("macro definition");
Douglas Gregor48072312010-03-18 15:23:44 +00003229 case CXCursor_MacroInstantiation:
3230 return createCXString("macro instantiation");
Douglas Gregorecdcb882010-10-20 22:00:55 +00003231 case CXCursor_InclusionDirective:
3232 return createCXString("inclusion directive");
Ted Kremenek8f06e0e2010-05-06 23:38:21 +00003233 case CXCursor_Namespace:
3234 return createCXString("Namespace");
Ted Kremeneka0536d82010-05-07 01:04:29 +00003235 case CXCursor_LinkageSpec:
3236 return createCXString("LinkageSpec");
Ted Kremenek3064ef92010-08-27 21:34:58 +00003237 case CXCursor_CXXBaseSpecifier:
3238 return createCXString("C++ base class specifier");
Douglas Gregor01829d32010-08-31 14:41:23 +00003239 case CXCursor_Constructor:
3240 return createCXString("CXXConstructor");
3241 case CXCursor_Destructor:
3242 return createCXString("CXXDestructor");
3243 case CXCursor_ConversionFunction:
3244 return createCXString("CXXConversion");
Douglas Gregorfe72e9c2010-08-31 17:01:39 +00003245 case CXCursor_TemplateTypeParameter:
3246 return createCXString("TemplateTypeParameter");
3247 case CXCursor_NonTypeTemplateParameter:
3248 return createCXString("NonTypeTemplateParameter");
3249 case CXCursor_TemplateTemplateParameter:
3250 return createCXString("TemplateTemplateParameter");
3251 case CXCursor_FunctionTemplate:
3252 return createCXString("FunctionTemplate");
Douglas Gregor39d6f072010-08-31 19:02:00 +00003253 case CXCursor_ClassTemplate:
3254 return createCXString("ClassTemplate");
Douglas Gregor74dbe642010-08-31 19:31:58 +00003255 case CXCursor_ClassTemplatePartialSpecialization:
3256 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregor69319002010-08-31 23:48:11 +00003257 case CXCursor_NamespaceAlias:
3258 return createCXString("NamespaceAlias");
Douglas Gregor0a35bce2010-09-01 03:07:18 +00003259 case CXCursor_UsingDirective:
3260 return createCXString("UsingDirective");
Douglas Gregor7e242562010-09-01 19:52:22 +00003261 case CXCursor_UsingDeclaration:
3262 return createCXString("UsingDeclaration");
Steve Naroff89922f82009-08-31 00:59:03 +00003263 }
Ted Kremeneke68fff62010-02-17 00:41:32 +00003264
Ted Kremenekdeb06bd2010-01-16 02:02:09 +00003265 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremeneka60ed472010-11-16 08:15:36 +00003266 return createCXString((const char*) 0);
Steve Naroff600866c2009-08-27 19:51:58 +00003267}
Steve Naroff89922f82009-08-31 00:59:03 +00003268
Ted Kremeneke68fff62010-02-17 00:41:32 +00003269enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3270 CXCursor parent,
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003271 CXClientData client_data) {
3272 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor93798e22010-11-05 21:11:19 +00003273
3274 // If our current best cursor is the construction of a temporary object,
3275 // don't replace that cursor with a type reference, because we want
3276 // clang_getCursor() to point at the constructor.
3277 if (clang_isExpression(BestCursor->kind) &&
3278 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3279 cursor.kind == CXCursor_TypeRef)
3280 return CXChildVisit_Recurse;
3281
Douglas Gregor85fe1562010-12-10 07:23:11 +00003282 // Don't override a preprocessing cursor with another preprocessing
3283 // cursor; we want the outermost preprocessing cursor.
3284 if (clang_isPreprocessing(cursor.kind) &&
3285 clang_isPreprocessing(BestCursor->kind))
3286 return CXChildVisit_Recurse;
3287
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003288 *BestCursor = cursor;
3289 return CXChildVisit_Recurse;
3290}
Ted Kremeneke68fff62010-02-17 00:41:32 +00003291
Douglas Gregorb9790342010-01-22 21:44:22 +00003292CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3293 if (!TU)
Ted Kremenekf4629892010-01-14 01:51:23 +00003294 return clang_getNullCursor();
Ted Kremeneke68fff62010-02-17 00:41:32 +00003295
Ted Kremeneka60ed472010-11-16 08:15:36 +00003296 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorbdf60622010-03-05 21:16:25 +00003297 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3298
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003299 // Translate the given source location to make it point at the beginning of
3300 // the token under the cursor.
Ted Kremeneka297de22010-01-25 22:34:44 +00003301 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremeneka629ea42010-07-29 00:52:07 +00003302
3303 // Guard against an invalid SourceLocation, or we may assert in one
3304 // of the following calls.
3305 if (SLoc.isInvalid())
3306 return clang_getNullCursor();
3307
Douglas Gregor40749ee2010-11-03 00:35:38 +00003308 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003309 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3310 CXXUnit->getASTContext().getLangOptions());
3311
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003312 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3313 if (SLoc.isValid()) {
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003314 // FIXME: Would be great to have a "hint" cursor, then walk from that
3315 // hint cursor upward until we find a cursor whose source range encloses
3316 // the region of interest, rather than starting from the translation unit.
Ted Kremeneka60ed472010-11-16 08:15:36 +00003317 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3318 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003319 Decl::MaxPCHLevel, SourceLocation(SLoc));
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003320 CursorVis.VisitChildren(Parent);
Steve Naroff77128dd2009-09-15 20:25:34 +00003321 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003322
3323 if (Logging) {
3324 CXFile SearchFile;
3325 unsigned SearchLine, SearchColumn;
3326 CXFile ResultFile;
3327 unsigned ResultLine, ResultColumn;
Douglas Gregor66537982010-11-17 17:14:07 +00003328 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3329 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor40749ee2010-11-03 00:35:38 +00003330 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3331
3332 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3333 0);
3334 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3335 &ResultColumn, 0);
3336 SearchFileName = clang_getFileName(SearchFile);
3337 ResultFileName = clang_getFileName(ResultFile);
3338 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor66537982010-11-17 17:14:07 +00003339 USR = clang_getCursorUSR(Result);
3340 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor40749ee2010-11-03 00:35:38 +00003341 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3342 clang_getCString(KindSpelling),
Douglas Gregor66537982010-11-17 17:14:07 +00003343 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3344 clang_getCString(USR), IsDef);
Douglas Gregor40749ee2010-11-03 00:35:38 +00003345 clang_disposeString(SearchFileName);
3346 clang_disposeString(ResultFileName);
3347 clang_disposeString(KindSpelling);
Douglas Gregor66537982010-11-17 17:14:07 +00003348 clang_disposeString(USR);
Douglas Gregor0aefbd82010-12-10 01:45:00 +00003349
3350 CXCursor Definition = clang_getCursorDefinition(Result);
3351 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3352 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3353 CXString DefinitionKindSpelling
3354 = clang_getCursorKindSpelling(Definition.kind);
3355 CXFile DefinitionFile;
3356 unsigned DefinitionLine, DefinitionColumn;
3357 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3358 &DefinitionLine, &DefinitionColumn, 0);
3359 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3360 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3361 clang_getCString(DefinitionKindSpelling),
3362 clang_getCString(DefinitionFileName),
3363 DefinitionLine, DefinitionColumn);
3364 clang_disposeString(DefinitionFileName);
3365 clang_disposeString(DefinitionKindSpelling);
3366 }
Douglas Gregor40749ee2010-11-03 00:35:38 +00003367 }
3368
Ted Kremeneke68fff62010-02-17 00:41:32 +00003369 return Result;
Steve Naroff600866c2009-08-27 19:51:58 +00003370}
3371
Ted Kremenek73885552009-11-17 19:28:59 +00003372CXCursor clang_getNullCursor(void) {
Douglas Gregor5bfb8c12010-01-20 23:34:41 +00003373 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremenek73885552009-11-17 19:28:59 +00003374}
3375
3376unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregor283cae32010-01-15 21:56:13 +00003377 return X == Y;
Ted Kremenek73885552009-11-17 19:28:59 +00003378}
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00003379
Douglas Gregor9ce55842010-11-20 00:09:34 +00003380unsigned clang_hashCursor(CXCursor C) {
3381 unsigned Index = 0;
3382 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3383 Index = 1;
3384
3385 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3386 std::make_pair(C.kind, C.data[Index]));
3387}
3388
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003389unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff77128dd2009-09-15 20:25:34 +00003390 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3391}
3392
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003393unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff89922f82009-08-31 00:59:03 +00003394 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3395}
Steve Naroff2d4d6292009-08-31 14:26:51 +00003396
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003397unsigned clang_isReference(enum CXCursorKind K) {
Steve Narofff334b4e2009-09-02 18:26:48 +00003398 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3399}
3400
Douglas Gregor97b98722010-01-19 23:20:36 +00003401unsigned clang_isExpression(enum CXCursorKind K) {
3402 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3403}
3404
3405unsigned clang_isStatement(enum CXCursorKind K) {
3406 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3407}
3408
Douglas Gregor7eaa8ae2010-01-20 00:23:15 +00003409unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3410 return K == CXCursor_TranslationUnit;
3411}
3412
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003413unsigned clang_isPreprocessing(enum CXCursorKind K) {
3414 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3415}
3416
Ted Kremenekad6eff62010-03-08 21:17:29 +00003417unsigned clang_isUnexposed(enum CXCursorKind K) {
3418 switch (K) {
3419 case CXCursor_UnexposedDecl:
3420 case CXCursor_UnexposedExpr:
3421 case CXCursor_UnexposedStmt:
3422 case CXCursor_UnexposedAttr:
3423 return true;
3424 default:
3425 return false;
3426 }
3427}
3428
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00003429CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroff9efa7672009-09-04 15:44:05 +00003430 return C.kind;
3431}
3432
Douglas Gregor98258af2010-01-18 22:46:11 +00003433CXSourceLocation clang_getCursorLocation(CXCursor C) {
3434 if (clang_isReference(C.kind)) {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003435 switch (C.kind) {
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003436 case CXCursor_ObjCSuperClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003437 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3438 = getCursorObjCSuperClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003439 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003440 }
3441
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003442 case CXCursor_ObjCProtocolRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003443 std::pair<ObjCProtocolDecl *, SourceLocation> P
3444 = getCursorObjCProtocolRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003445 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003446 }
3447
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003448 case CXCursor_ObjCClassRef: {
Douglas Gregorf46034a2010-01-18 23:41:10 +00003449 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3450 = getCursorObjCClassRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003451 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003452 }
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003453
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003454 case CXCursor_TypeRef: {
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003455 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremeneka297de22010-01-25 22:34:44 +00003456 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003457 }
Douglas Gregor0b36e612010-08-31 20:37:03 +00003458
3459 case CXCursor_TemplateRef: {
3460 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3461 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3462 }
3463
Douglas Gregor69319002010-08-31 23:48:11 +00003464 case CXCursor_NamespaceRef: {
3465 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3466 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3467 }
3468
Douglas Gregora67e03f2010-09-09 21:42:20 +00003469 case CXCursor_MemberRef: {
3470 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3471 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3472 }
3473
Ted Kremenek3064ef92010-08-27 21:34:58 +00003474 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003475 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3476 if (!BaseSpec)
3477 return clang_getNullLocation();
3478
3479 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3480 return cxloc::translateSourceLocation(getCursorContext(C),
3481 TSInfo->getTypeLoc().getBeginLoc());
3482
3483 return cxloc::translateSourceLocation(getCursorContext(C),
3484 BaseSpec->getSourceRange().getBegin());
Ted Kremenek3064ef92010-08-27 21:34:58 +00003485 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003486
Douglas Gregor36897b02010-09-10 00:22:18 +00003487 case CXCursor_LabelRef: {
3488 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3489 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3490 }
3491
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003492 case CXCursor_OverloadedDeclRef:
3493 return cxloc::translateSourceLocation(getCursorContext(C),
3494 getCursorOverloadedDeclRef(C).second);
3495
Douglas Gregorf46034a2010-01-18 23:41:10 +00003496 default:
3497 // FIXME: Need a way to enumerate all non-reference cases.
3498 llvm_unreachable("Missed a reference kind");
3499 }
Douglas Gregor98258af2010-01-18 22:46:11 +00003500 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003501
3502 if (clang_isExpression(C.kind))
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003503 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor97b98722010-01-19 23:20:36 +00003504 getLocationFromExpr(getCursorExpr(C)));
3505
Douglas Gregor36897b02010-09-10 00:22:18 +00003506 if (clang_isStatement(C.kind))
3507 return cxloc::translateSourceLocation(getCursorContext(C),
3508 getCursorStmt(C)->getLocStart());
3509
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00003510 if (C.kind == CXCursor_PreprocessingDirective) {
3511 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3512 return cxloc::translateSourceLocation(getCursorContext(C), L);
3513 }
Douglas Gregor48072312010-03-18 15:23:44 +00003514
3515 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor4ae8f292010-03-18 17:52:52 +00003516 SourceLocation L
3517 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor48072312010-03-18 15:23:44 +00003518 return cxloc::translateSourceLocation(getCursorContext(C), L);
3519 }
Douglas Gregor572feb22010-03-18 18:04:21 +00003520
3521 if (C.kind == CXCursor_MacroDefinition) {
3522 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3523 return cxloc::translateSourceLocation(getCursorContext(C), L);
3524 }
Douglas Gregorecdcb882010-10-20 22:00:55 +00003525
3526 if (C.kind == CXCursor_InclusionDirective) {
3527 SourceLocation L
3528 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3529 return cxloc::translateSourceLocation(getCursorContext(C), L);
3530 }
3531
Ted Kremenek9a700d22010-05-12 06:16:13 +00003532 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor5352ac02010-01-28 00:27:43 +00003533 return clang_getNullLocation();
Douglas Gregor98258af2010-01-18 22:46:11 +00003534
Douglas Gregorf46034a2010-01-18 23:41:10 +00003535 Decl *D = getCursorDecl(C);
Douglas Gregorf46034a2010-01-18 23:41:10 +00003536 SourceLocation Loc = D->getLocation();
3537 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3538 Loc = Class->getClassLoc();
Ted Kremenek007a7c92010-11-01 23:26:51 +00003539 // FIXME: Multiple variables declared in a single declaration
3540 // currently lack the information needed to correctly determine their
3541 // ranges when accounting for the type-specifier. We use context
3542 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3543 // and if so, whether it is the first decl.
3544 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3545 if (!cxcursor::isFirstInDeclGroup(C))
3546 Loc = VD->getLocation();
3547 }
3548
Douglas Gregor2ca54fe2010-03-22 15:53:50 +00003549 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor98258af2010-01-18 22:46:11 +00003550}
Douglas Gregora7bde202010-01-19 00:34:46 +00003551
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003552} // end extern "C"
3553
3554static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregora7bde202010-01-19 00:34:46 +00003555 if (clang_isReference(C.kind)) {
3556 switch (C.kind) {
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003557 case CXCursor_ObjCSuperClassRef:
3558 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003559
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003560 case CXCursor_ObjCProtocolRef:
3561 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003562
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003563 case CXCursor_ObjCClassRef:
3564 return getCursorObjCClassRef(C).second;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003565
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003566 case CXCursor_TypeRef:
3567 return getCursorTypeRef(C).second;
Douglas Gregor0b36e612010-08-31 20:37:03 +00003568
3569 case CXCursor_TemplateRef:
3570 return getCursorTemplateRef(C).second;
3571
Douglas Gregor69319002010-08-31 23:48:11 +00003572 case CXCursor_NamespaceRef:
3573 return getCursorNamespaceRef(C).second;
Douglas Gregora67e03f2010-09-09 21:42:20 +00003574
3575 case CXCursor_MemberRef:
3576 return getCursorMemberRef(C).second;
3577
Ted Kremenek3064ef92010-08-27 21:34:58 +00003578 case CXCursor_CXXBaseSpecifier:
Douglas Gregor1b0f7af2010-10-02 19:51:13 +00003579 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003580
Douglas Gregor36897b02010-09-10 00:22:18 +00003581 case CXCursor_LabelRef:
3582 return getCursorLabelRef(C).second;
3583
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003584 case CXCursor_OverloadedDeclRef:
3585 return getCursorOverloadedDeclRef(C).second;
3586
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003587 default:
3588 // FIXME: Need a way to enumerate all non-reference cases.
3589 llvm_unreachable("Missed a reference kind");
Douglas Gregora7bde202010-01-19 00:34:46 +00003590 }
3591 }
Douglas Gregor97b98722010-01-19 23:20:36 +00003592
3593 if (clang_isExpression(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003594 return getCursorExpr(C)->getSourceRange();
Douglas Gregor33e9abd2010-01-22 19:49:59 +00003595
3596 if (clang_isStatement(C.kind))
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003597 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003598
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003599 if (C.kind == CXCursor_PreprocessingDirective)
3600 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor48072312010-03-18 15:23:44 +00003601
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003602 if (C.kind == CXCursor_MacroInstantiation)
3603 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor572feb22010-03-18 18:04:21 +00003604
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003605 if (C.kind == CXCursor_MacroDefinition)
3606 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregorecdcb882010-10-20 22:00:55 +00003607
3608 if (C.kind == CXCursor_InclusionDirective)
3609 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3610
Ted Kremenek007a7c92010-11-01 23:26:51 +00003611 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3612 Decl *D = cxcursor::getCursorDecl(C);
3613 SourceRange R = D->getSourceRange();
3614 // FIXME: Multiple variables declared in a single declaration
3615 // currently lack the information needed to correctly determine their
3616 // ranges when accounting for the type-specifier. We use context
3617 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3618 // and if so, whether it is the first decl.
3619 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3620 if (!cxcursor::isFirstInDeclGroup(C))
3621 R.setBegin(VD->getLocation());
3622 }
3623 return R;
3624 }
Douglas Gregor66537982010-11-17 17:14:07 +00003625 return SourceRange();
3626}
3627
3628/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3629/// the decl-specifier-seq for declarations.
3630static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3631 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3632 Decl *D = cxcursor::getCursorDecl(C);
3633 SourceRange R = D->getSourceRange();
Douglas Gregor66537982010-11-17 17:14:07 +00003634
Douglas Gregor2494dd02011-03-01 01:34:45 +00003635 // Adjust the start of the location for declarations preceded by
3636 // declaration specifiers.
3637 SourceLocation StartLoc;
3638 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3639 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3640 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3641 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3642 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3643 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3644 }
3645
3646 if (StartLoc.isValid() && R.getBegin().isValid() &&
3647 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3648 R.setBegin(StartLoc);
3649
3650 // FIXME: Multiple variables declared in a single declaration
3651 // currently lack the information needed to correctly determine their
3652 // ranges when accounting for the type-specifier. We use context
3653 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3654 // and if so, whether it is the first decl.
3655 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3656 if (!cxcursor::isFirstInDeclGroup(C))
3657 R.setBegin(VD->getLocation());
Douglas Gregor66537982010-11-17 17:14:07 +00003658 }
3659
3660 return R;
3661 }
3662
3663 return getRawCursorExtent(C);
3664}
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003665
3666extern "C" {
3667
3668CXSourceRange clang_getCursorExtent(CXCursor C) {
3669 SourceRange R = getRawCursorExtent(C);
3670 if (R.isInvalid())
Douglas Gregor5352ac02010-01-28 00:27:43 +00003671 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003672
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00003673 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregora7bde202010-01-19 00:34:46 +00003674}
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003675
3676CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003677 if (clang_isInvalid(C.kind))
3678 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003679
Ted Kremeneka60ed472010-11-16 08:15:36 +00003680 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003681 if (clang_isDeclaration(C.kind)) {
3682 Decl *D = getCursorDecl(C);
3683 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003684 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003685 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003686 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003687 if (ObjCForwardProtocolDecl *Protocols
3688 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003689 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregore3c60a72010-11-17 00:13:31 +00003690 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3691 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3692 return MakeCXCursor(Property, tu);
3693
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003694 return C;
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003695 }
3696
Douglas Gregor97b98722010-01-19 23:20:36 +00003697 if (clang_isExpression(C.kind)) {
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003698 Expr *E = getCursorExpr(C);
3699 Decl *D = getDeclFromExpr(E);
Douglas Gregor97b98722010-01-19 23:20:36 +00003700 if (D)
Ted Kremeneka60ed472010-11-16 08:15:36 +00003701 return MakeCXCursor(D, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003702
3703 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003704 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003705
Douglas Gregor97b98722010-01-19 23:20:36 +00003706 return clang_getNullCursor();
3707 }
3708
Douglas Gregor36897b02010-09-10 00:22:18 +00003709 if (clang_isStatement(C.kind)) {
3710 Stmt *S = getCursorStmt(C);
3711 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003712 return MakeCXCursor(Goto->getLabel()->getStmt(), getCursorDecl(C), tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003713
3714 return clang_getNullCursor();
3715 }
3716
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003717 if (C.kind == CXCursor_MacroInstantiation) {
3718 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003719 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003720 }
3721
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003722 if (!clang_isReference(C.kind))
3723 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003724
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003725 switch (C.kind) {
3726 case CXCursor_ObjCSuperClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003727 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003728
3729 case CXCursor_ObjCProtocolRef: {
Ted Kremeneka60ed472010-11-16 08:15:36 +00003730 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003731
3732 case CXCursor_ObjCClassRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003733 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor7d0d40e2010-01-21 16:28:34 +00003734
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003735 case CXCursor_TypeRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003736 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003737
3738 case CXCursor_TemplateRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003739 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregor0b36e612010-08-31 20:37:03 +00003740
Douglas Gregor69319002010-08-31 23:48:11 +00003741 case CXCursor_NamespaceRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003742 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregor69319002010-08-31 23:48:11 +00003743
Douglas Gregora67e03f2010-09-09 21:42:20 +00003744 case CXCursor_MemberRef:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003745 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregora67e03f2010-09-09 21:42:20 +00003746
Ted Kremenek3064ef92010-08-27 21:34:58 +00003747 case CXCursor_CXXBaseSpecifier: {
3748 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3749 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003750 tu ));
Ted Kremenek3064ef92010-08-27 21:34:58 +00003751 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003752
Douglas Gregor36897b02010-09-10 00:22:18 +00003753 case CXCursor_LabelRef:
3754 // FIXME: We end up faking the "parent" declaration here because we
3755 // don't want to make CXCursor larger.
3756 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremeneka60ed472010-11-16 08:15:36 +00003757 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3758 .getTranslationUnitDecl(),
3759 tu);
Douglas Gregor36897b02010-09-10 00:22:18 +00003760
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003761 case CXCursor_OverloadedDeclRef:
3762 return C;
3763
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003764 default:
3765 // We would prefer to enumerate all non-reference cursor kinds here.
3766 llvm_unreachable("Unhandled reference cursor kind");
3767 break;
3768 }
3769 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003770
Douglas Gregorc5d1e932010-01-19 01:20:04 +00003771 return clang_getNullCursor();
3772}
3773
Douglas Gregorb6998662010-01-19 19:34:47 +00003774CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003775 if (clang_isInvalid(C.kind))
3776 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003777
Ted Kremeneka60ed472010-11-16 08:15:36 +00003778 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003779
Douglas Gregorb6998662010-01-19 19:34:47 +00003780 bool WasReference = false;
Douglas Gregor97b98722010-01-19 23:20:36 +00003781 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregorb6998662010-01-19 19:34:47 +00003782 C = clang_getCursorReferenced(C);
3783 WasReference = true;
3784 }
3785
Douglas Gregorbf7efa22010-03-18 18:23:03 +00003786 if (C.kind == CXCursor_MacroInstantiation)
3787 return clang_getCursorReferenced(C);
3788
Douglas Gregorb6998662010-01-19 19:34:47 +00003789 if (!clang_isDeclaration(C.kind))
3790 return clang_getNullCursor();
3791
3792 Decl *D = getCursorDecl(C);
3793 if (!D)
3794 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003795
Douglas Gregorb6998662010-01-19 19:34:47 +00003796 switch (D->getKind()) {
3797 // Declaration kinds that don't really separate the notions of
3798 // declaration and definition.
3799 case Decl::Namespace:
3800 case Decl::Typedef:
3801 case Decl::TemplateTypeParm:
3802 case Decl::EnumConstant:
3803 case Decl::Field:
Benjamin Kramerd9811462010-11-21 14:11:41 +00003804 case Decl::IndirectField:
Douglas Gregorb6998662010-01-19 19:34:47 +00003805 case Decl::ObjCIvar:
3806 case Decl::ObjCAtDefsField:
3807 case Decl::ImplicitParam:
3808 case Decl::ParmVar:
3809 case Decl::NonTypeTemplateParm:
3810 case Decl::TemplateTemplateParm:
3811 case Decl::ObjCCategoryImpl:
3812 case Decl::ObjCImplementation:
Abramo Bagnara6206d532010-06-05 05:09:32 +00003813 case Decl::AccessSpec:
Douglas Gregorb6998662010-01-19 19:34:47 +00003814 case Decl::LinkageSpec:
3815 case Decl::ObjCPropertyImpl:
3816 case Decl::FileScopeAsm:
3817 case Decl::StaticAssert:
3818 case Decl::Block:
Chris Lattnerad8dcf42011-02-17 07:39:24 +00003819 case Decl::Label: // FIXME: Is this right??
Douglas Gregorb6998662010-01-19 19:34:47 +00003820 return C;
3821
3822 // Declaration kinds that don't make any sense here, but are
3823 // nonetheless harmless.
3824 case Decl::TranslationUnit:
Douglas Gregorb6998662010-01-19 19:34:47 +00003825 break;
3826
3827 // Declaration kinds for which the definition is not resolvable.
3828 case Decl::UnresolvedUsingTypename:
3829 case Decl::UnresolvedUsingValue:
3830 break;
3831
3832 case Decl::UsingDirective:
Douglas Gregorb2cd4872010-01-20 23:57:43 +00003833 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003834 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003835
3836 case Decl::NamespaceAlias:
Ted Kremeneka60ed472010-11-16 08:15:36 +00003837 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003838
3839 case Decl::Enum:
3840 case Decl::Record:
3841 case Decl::CXXRecord:
3842 case Decl::ClassTemplateSpecialization:
3843 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor952b0172010-02-11 01:04:33 +00003844 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003845 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003846 return clang_getNullCursor();
3847
3848 case Decl::Function:
3849 case Decl::CXXMethod:
3850 case Decl::CXXConstructor:
3851 case Decl::CXXDestructor:
3852 case Decl::CXXConversion: {
3853 const FunctionDecl *Def = 0;
3854 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003855 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003856 return clang_getNullCursor();
3857 }
3858
3859 case Decl::Var: {
Sebastian Redl31310a22010-02-01 20:16:42 +00003860 // Ask the variable if it has a definition.
3861 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003862 return MakeCXCursor(Def, TU);
Sebastian Redl31310a22010-02-01 20:16:42 +00003863 return clang_getNullCursor();
Douglas Gregorb6998662010-01-19 19:34:47 +00003864 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003865
Douglas Gregorb6998662010-01-19 19:34:47 +00003866 case Decl::FunctionTemplate: {
3867 const FunctionDecl *Def = 0;
3868 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremeneka60ed472010-11-16 08:15:36 +00003869 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003870 return clang_getNullCursor();
3871 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003872
Douglas Gregorb6998662010-01-19 19:34:47 +00003873 case Decl::ClassTemplate: {
3874 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor952b0172010-02-11 01:04:33 +00003875 ->getDefinition())
Douglas Gregor0b36e612010-08-31 20:37:03 +00003876 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003877 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003878 return clang_getNullCursor();
3879 }
3880
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003881 case Decl::Using:
3882 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003883 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003884
3885 case Decl::UsingShadow:
3886 return clang_getCursorDefinition(
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003887 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003888 TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003889
3890 case Decl::ObjCMethod: {
3891 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3892 if (Method->isThisDeclarationADefinition())
3893 return C;
3894
3895 // Dig out the method definition in the associated
3896 // @implementation, if we have it.
3897 // FIXME: The ASTs should make finding the definition easier.
3898 if (ObjCInterfaceDecl *Class
3899 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3900 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3901 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3902 Method->isInstanceMethod()))
3903 if (Def->isThisDeclarationADefinition())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003904 return MakeCXCursor(Def, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003905
3906 return clang_getNullCursor();
3907 }
3908
3909 case Decl::ObjCCategory:
3910 if (ObjCCategoryImplDecl *Impl
3911 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003912 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003913 return clang_getNullCursor();
3914
3915 case Decl::ObjCProtocol:
3916 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3917 return C;
3918 return clang_getNullCursor();
3919
3920 case Decl::ObjCInterface:
3921 // There are two notions of a "definition" for an Objective-C
3922 // class: the interface and its implementation. When we resolved a
3923 // reference to an Objective-C class, produce the @interface as
3924 // the definition; when we were provided with the interface,
3925 // produce the @implementation as the definition.
3926 if (WasReference) {
3927 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
3928 return C;
3929 } else if (ObjCImplementationDecl *Impl
3930 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003931 return MakeCXCursor(Impl, TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003932 return clang_getNullCursor();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003933
Douglas Gregorb6998662010-01-19 19:34:47 +00003934 case Decl::ObjCProperty:
3935 // FIXME: We don't really know where to find the
3936 // ObjCPropertyImplDecls that implement this property.
3937 return clang_getNullCursor();
3938
3939 case Decl::ObjCCompatibleAlias:
3940 if (ObjCInterfaceDecl *Class
3941 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
3942 if (!Class->isForwardDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003943 return MakeCXCursor(Class, TU);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00003944
Douglas Gregorb6998662010-01-19 19:34:47 +00003945 return clang_getNullCursor();
3946
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003947 case Decl::ObjCForwardProtocol:
3948 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003949 D->getLocation(), TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003950
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003951 case Decl::ObjCClass:
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00003952 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremeneka60ed472010-11-16 08:15:36 +00003953 TU);
Douglas Gregorb6998662010-01-19 19:34:47 +00003954
3955 case Decl::Friend:
3956 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003957 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003958 return clang_getNullCursor();
3959
3960 case Decl::FriendTemplate:
3961 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremeneka60ed472010-11-16 08:15:36 +00003962 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregorb6998662010-01-19 19:34:47 +00003963 return clang_getNullCursor();
3964 }
3965
3966 return clang_getNullCursor();
3967}
3968
3969unsigned clang_isCursorDefinition(CXCursor C) {
3970 if (!clang_isDeclaration(C.kind))
3971 return 0;
3972
3973 return clang_getCursorDefinition(C) == C;
3974}
3975
Douglas Gregor1a9d0502010-11-19 23:44:15 +00003976CXCursor clang_getCanonicalCursor(CXCursor C) {
3977 if (!clang_isDeclaration(C.kind))
3978 return C;
3979
3980 if (Decl *D = getCursorDecl(C))
3981 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
3982
3983 return C;
3984}
3985
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003986unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00003987 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00003988 return 0;
3989
3990 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3991 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3992 return E->getNumDecls();
3993
3994 if (OverloadedTemplateStorage *S
3995 = Storage.dyn_cast<OverloadedTemplateStorage*>())
3996 return S->size();
3997
3998 Decl *D = Storage.get<Decl*>();
3999 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis826faa22010-11-10 05:40:41 +00004000 return Using->shadow_size();
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004001 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4002 return Classes->size();
4003 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4004 return Protocols->protocol_size();
4005
4006 return 0;
4007}
4008
4009CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregor7c432dd2010-09-16 13:54:00 +00004010 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004011 return clang_getNullCursor();
4012
4013 if (index >= clang_getNumOverloadedDecls(cursor))
4014 return clang_getNullCursor();
4015
Ted Kremeneka60ed472010-11-16 08:15:36 +00004016 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004017 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4018 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004019 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004020
4021 if (OverloadedTemplateStorage *S
4022 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremeneka60ed472010-11-16 08:15:36 +00004023 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004024
4025 Decl *D = Storage.get<Decl*>();
4026 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4027 // FIXME: This is, unfortunately, linear time.
4028 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4029 std::advance(Pos, index);
Ted Kremeneka60ed472010-11-16 08:15:36 +00004030 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004031 }
4032
4033 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004034 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004035
4036 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004037 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor1f60d9e2010-09-13 22:52:57 +00004038
4039 return clang_getNullCursor();
4040}
4041
Daniel Dunbar0d7dd222009-11-30 20:42:43 +00004042void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff4ade6d62009-09-23 17:52:52 +00004043 const char **startBuf,
4044 const char **endBuf,
4045 unsigned *startLine,
4046 unsigned *startColumn,
4047 unsigned *endLine,
Daniel Dunbar9ebfa312009-12-01 03:14:51 +00004048 unsigned *endColumn) {
Douglas Gregor283cae32010-01-15 21:56:13 +00004049 assert(getCursorDecl(C) && "CXCursor has null decl");
4050 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff4ade6d62009-09-23 17:52:52 +00004051 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4052 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004053
Steve Naroff4ade6d62009-09-23 17:52:52 +00004054 SourceManager &SM = FD->getASTContext().getSourceManager();
4055 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4056 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4057 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4058 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4059 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4060 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4061}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004062
Douglas Gregor0a812cf2010-02-18 23:07:20 +00004063void clang_enableStackTraces(void) {
4064 llvm::sys::PrintStackTraceOnErrorSignal();
4065}
4066
Daniel Dunbar995aaf92010-11-04 01:26:29 +00004067void clang_executeOnThread(void (*fn)(void*), void *user_data,
4068 unsigned stack_size) {
4069 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4070}
4071
Ted Kremenekfb480492010-01-13 21:46:36 +00004072} // end: extern "C"
Steve Naroff4ade6d62009-09-23 17:52:52 +00004073
Ted Kremenekfb480492010-01-13 21:46:36 +00004074//===----------------------------------------------------------------------===//
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004075// Token-based Operations.
4076//===----------------------------------------------------------------------===//
4077
4078/* CXToken layout:
4079 * int_data[0]: a CXTokenKind
4080 * int_data[1]: starting token location
4081 * int_data[2]: token length
4082 * int_data[3]: reserved
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004083 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004084 * otherwise unused.
4085 */
4086extern "C" {
4087
4088CXTokenKind clang_getTokenKind(CXToken CXTok) {
4089 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4090}
4091
4092CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4093 switch (clang_getTokenKind(CXTok)) {
4094 case CXToken_Identifier:
4095 case CXToken_Keyword:
4096 // We know we have an IdentifierInfo*, so use that.
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004097 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4098 ->getNameStart());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004099
4100 case CXToken_Literal: {
4101 // We have stashed the starting pointer in the ptr_data field. Use it.
4102 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004103 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004104 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004105
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004106 case CXToken_Punctuation:
4107 case CXToken_Comment:
4108 break;
4109 }
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004110
4111 // We have to find the starting buffer pointer the hard way, by
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004112 // deconstructing the source location.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004113 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004114 if (!CXXUnit)
Ted Kremenekee4db4f2010-02-17 00:41:08 +00004115 return createCXString("");
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004116
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004117 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4118 std::pair<FileID, unsigned> LocInfo
4119 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregorf715ca12010-03-16 00:06:06 +00004120 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004121 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004122 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4123 if (Invalid)
Douglas Gregoraea67db2010-03-15 22:54:52 +00004124 return createCXString("");
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004125
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004126 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004127}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004128
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004129CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004130 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004131 if (!CXXUnit)
4132 return clang_getNullLocation();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004133
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004134 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4135 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4136}
4137
4138CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004139 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor5352ac02010-01-28 00:27:43 +00004140 if (!CXXUnit)
4141 return clang_getNullRange();
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004142
4143 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004144 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4145}
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004146
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004147void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4148 CXToken **Tokens, unsigned *NumTokens) {
4149 if (Tokens)
4150 *Tokens = 0;
4151 if (NumTokens)
4152 *NumTokens = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004153
Ted Kremeneka60ed472010-11-16 08:15:36 +00004154 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004155 if (!CXXUnit || !Tokens || !NumTokens)
4156 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004157
Douglas Gregorbdf60622010-03-05 21:16:25 +00004158 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4159
Daniel Dunbar85b988f2010-02-14 08:31:57 +00004160 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004161 if (R.isInvalid())
4162 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004163
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004164 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4165 std::pair<FileID, unsigned> BeginLocInfo
4166 = SourceMgr.getDecomposedLoc(R.getBegin());
4167 std::pair<FileID, unsigned> EndLocInfo
4168 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004169
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004170 // Cannot tokenize across files.
4171 if (BeginLocInfo.first != EndLocInfo.first)
4172 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004173
4174 // Create a lexer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004175 bool Invalid = false;
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004176 llvm::StringRef Buffer
Douglas Gregorf715ca12010-03-16 00:06:06 +00004177 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor47a3fcd2010-03-16 20:26:15 +00004178 if (Invalid)
4179 return;
Douglas Gregoraea67db2010-03-15 22:54:52 +00004180
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004181 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4182 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004183 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004184 Lex.SetCommentRetentionState(true);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004185
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004186 // Lex tokens until we hit the end of the range.
Benjamin Kramerf6ac97b2010-03-16 14:14:31 +00004187 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004188 llvm::SmallVector<CXToken, 32> CXTokens;
4189 Token Tok;
David Chisnall096428b2010-10-13 21:44:48 +00004190 bool previousWasAt = false;
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004191 do {
4192 // Lex the next token
4193 Lex.LexFromRawLexer(Tok);
4194 if (Tok.is(tok::eof))
4195 break;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004196
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004197 // Initialize the CXToken.
4198 CXToken CXTok;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004199
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004200 // - Common fields
4201 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4202 CXTok.int_data[2] = Tok.getLength();
4203 CXTok.int_data[3] = 0;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004204
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004205 // - Kind-specific fields
4206 if (Tok.isLiteral()) {
4207 CXTok.int_data[0] = CXToken_Literal;
4208 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004209 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregoraea67db2010-03-15 22:54:52 +00004210 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004211 IdentifierInfo *II
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004212 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004213
David Chisnall096428b2010-10-13 21:44:48 +00004214 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004215 CXTok.int_data[0] = CXToken_Keyword;
4216 }
4217 else {
Abramo Bagnarac4bf2b92010-12-22 08:23:18 +00004218 CXTok.int_data[0] = Tok.is(tok::identifier)
4219 ? CXToken_Identifier
4220 : CXToken_Keyword;
Ted Kremenekaa8a66d2010-05-05 00:55:20 +00004221 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004222 CXTok.ptr_data = II;
4223 } else if (Tok.is(tok::comment)) {
4224 CXTok.int_data[0] = CXToken_Comment;
4225 CXTok.ptr_data = 0;
4226 } else {
4227 CXTok.int_data[0] = CXToken_Punctuation;
4228 CXTok.ptr_data = 0;
4229 }
4230 CXTokens.push_back(CXTok);
David Chisnall096428b2010-10-13 21:44:48 +00004231 previousWasAt = Tok.is(tok::at);
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004232 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004233
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004234 if (CXTokens.empty())
4235 return;
Ted Kremenekf0e23e82010-02-17 00:41:40 +00004236
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004237 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4238 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4239 *NumTokens = CXTokens.size();
4240}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004241
Ted Kremenek6db61092010-05-05 00:55:15 +00004242void clang_disposeTokens(CXTranslationUnit TU,
4243 CXToken *Tokens, unsigned NumTokens) {
4244 free(Tokens);
4245}
4246
4247} // end: extern "C"
4248
4249//===----------------------------------------------------------------------===//
4250// Token annotation APIs.
4251//===----------------------------------------------------------------------===//
4252
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004253typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004254static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4255 CXCursor parent,
4256 CXClientData client_data);
Ted Kremenek6db61092010-05-05 00:55:15 +00004257namespace {
4258class AnnotateTokensWorker {
4259 AnnotateTokensData &Annotated;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004260 CXToken *Tokens;
4261 CXCursor *Cursors;
4262 unsigned NumTokens;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004263 unsigned TokIdx;
Douglas Gregor4419b672010-10-21 06:10:04 +00004264 unsigned PreprocessingTokIdx;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004265 CursorVisitor AnnotateVis;
4266 SourceManager &SrcMgr;
Douglas Gregorf5251602011-03-08 17:10:18 +00004267 bool HasContextSensitiveKeywords;
4268
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004269 bool MoreTokens() const { return TokIdx < NumTokens; }
4270 unsigned NextToken() const { return TokIdx; }
4271 void AdvanceToken() { ++TokIdx; }
4272 SourceLocation GetTokenLoc(unsigned tokI) {
4273 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4274 }
4275
Ted Kremenek6db61092010-05-05 00:55:15 +00004276public:
Ted Kremenek11949cb2010-05-05 00:55:17 +00004277 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004278 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004279 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek11949cb2010-05-05 00:55:17 +00004280 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregor4419b672010-10-21 06:10:04 +00004281 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004282 AnnotateVis(tu,
4283 AnnotateTokensVisitor, this,
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004284 Decl::MaxPCHLevel, RegionOfInterest),
Douglas Gregorf5251602011-03-08 17:10:18 +00004285 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4286 HasContextSensitiveKeywords(false) { }
Ted Kremenek11949cb2010-05-05 00:55:17 +00004287
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004288 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek6db61092010-05-05 00:55:15 +00004289 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004290 void AnnotateTokens(CXCursor parent);
Ted Kremenekab979612010-11-11 08:05:23 +00004291 void AnnotateTokens() {
Ted Kremeneka60ed472010-11-16 08:15:36 +00004292 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekab979612010-11-11 08:05:23 +00004293 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004294
4295 /// \brief Determine whether the annotator saw any cursors that have
4296 /// context-sensitive keywords.
4297 bool hasContextSensitiveKeywords() const {
4298 return HasContextSensitiveKeywords;
4299 }
Ted Kremenek6db61092010-05-05 00:55:15 +00004300};
4301}
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004302
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004303void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4304 // Walk the AST within the region of interest, annotating tokens
4305 // along the way.
4306 VisitChildren(parent);
Ted Kremenek11949cb2010-05-05 00:55:17 +00004307
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004308 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4309 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregor4419b672010-10-21 06:10:04 +00004310 if (Pos != Annotated.end() &&
4311 (clang_isInvalid(Cursors[I].kind) ||
4312 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004313 Cursors[I] = Pos->second;
4314 }
4315
4316 // Finish up annotating any tokens left.
4317 if (!MoreTokens())
4318 return;
4319
4320 const CXCursor &C = clang_getNullCursor();
4321 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4322 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4323 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek11949cb2010-05-05 00:55:17 +00004324 }
4325}
4326
Ted Kremenek6db61092010-05-05 00:55:15 +00004327enum CXChildVisitResult
Douglas Gregor4419b672010-10-21 06:10:04 +00004328AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004329 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregor4419b672010-10-21 06:10:04 +00004330 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor81d3c042010-11-01 20:13:04 +00004331 if (cursorRange.isInvalid())
4332 return CXChildVisit_Recurse;
Douglas Gregorf5251602011-03-08 17:10:18 +00004333
4334 if (!HasContextSensitiveKeywords) {
4335 // Objective-C properties can have context-sensitive keywords.
4336 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4337 if (ObjCPropertyDecl *Property
4338 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4339 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4340 }
4341 // Objective-C methods can have context-sensitive keywords.
4342 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4343 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4344 if (ObjCMethodDecl *Method
4345 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4346 if (Method->getObjCDeclQualifier())
4347 HasContextSensitiveKeywords = true;
4348 else {
4349 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4350 PEnd = Method->param_end();
4351 P != PEnd; ++P) {
4352 if ((*P)->getObjCDeclQualifier()) {
4353 HasContextSensitiveKeywords = true;
4354 break;
4355 }
4356 }
4357 }
4358 }
4359 }
4360 // C++ methods can have context-sensitive keywords.
4361 else if (cursor.kind == CXCursor_CXXMethod) {
4362 if (CXXMethodDecl *Method
4363 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4364 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4365 HasContextSensitiveKeywords = true;
4366 }
4367 }
4368 // C++ classes can have context-sensitive keywords.
4369 else if (cursor.kind == CXCursor_StructDecl ||
4370 cursor.kind == CXCursor_ClassDecl ||
4371 cursor.kind == CXCursor_ClassTemplate ||
4372 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4373 if (Decl *D = getCursorDecl(cursor))
4374 if (D->hasAttr<FinalAttr>())
4375 HasContextSensitiveKeywords = true;
4376 }
4377 }
4378
Douglas Gregor4419b672010-10-21 06:10:04 +00004379 if (clang_isPreprocessing(cursor.kind)) {
4380 // For macro instantiations, just note where the beginning of the macro
4381 // instantiation occurs.
4382 if (cursor.kind == CXCursor_MacroInstantiation) {
4383 Annotated[Loc.int_data] = cursor;
4384 return CXChildVisit_Recurse;
4385 }
4386
Douglas Gregor4419b672010-10-21 06:10:04 +00004387 // Items in the preprocessing record are kept separate from items in
4388 // declarations, so we keep a separate token index.
4389 unsigned SavedTokIdx = TokIdx;
4390 TokIdx = PreprocessingTokIdx;
4391
4392 // Skip tokens up until we catch up to the beginning of the preprocessing
4393 // entry.
4394 while (MoreTokens()) {
4395 const unsigned I = NextToken();
4396 SourceLocation TokLoc = GetTokenLoc(I);
4397 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4398 case RangeBefore:
4399 AdvanceToken();
4400 continue;
4401 case RangeAfter:
4402 case RangeOverlap:
4403 break;
4404 }
4405 break;
4406 }
4407
4408 // Look at all of the tokens within this range.
4409 while (MoreTokens()) {
4410 const unsigned I = NextToken();
4411 SourceLocation TokLoc = GetTokenLoc(I);
4412 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4413 case RangeBefore:
4414 assert(0 && "Infeasible");
4415 case RangeAfter:
4416 break;
4417 case RangeOverlap:
4418 Cursors[I] = cursor;
4419 AdvanceToken();
4420 continue;
4421 }
4422 break;
4423 }
4424
4425 // Save the preprocessing token index; restore the non-preprocessing
4426 // token index.
4427 PreprocessingTokIdx = TokIdx;
4428 TokIdx = SavedTokIdx;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004429 return CXChildVisit_Recurse;
4430 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004431
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004432 if (cursorRange.isInvalid())
4433 return CXChildVisit_Continue;
Ted Kremeneka333c662010-05-12 05:29:33 +00004434
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004435 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4436
Ted Kremeneka333c662010-05-12 05:29:33 +00004437 // Adjust the annotated range based specific declarations.
4438 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4439 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek23173d72010-05-18 21:09:07 +00004440 Decl *D = cxcursor::getCursorDecl(cursor);
4441 // Don't visit synthesized ObjC methods, since they have no syntatic
4442 // representation in the source.
4443 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4444 if (MD->isSynthesized())
4445 return CXChildVisit_Continue;
4446 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004447
4448 SourceLocation StartLoc;
Ted Kremenek23173d72010-05-18 21:09:07 +00004449 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor2494dd02011-03-01 01:34:45 +00004450 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4451 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4452 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4453 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4454 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremeneka333c662010-05-12 05:29:33 +00004455 }
Douglas Gregor2494dd02011-03-01 01:34:45 +00004456
4457 if (StartLoc.isValid() && L.isValid() &&
4458 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4459 cursorRange.setBegin(StartLoc);
Ted Kremeneka333c662010-05-12 05:29:33 +00004460 }
Douglas Gregor81d3c042010-11-01 20:13:04 +00004461
Ted Kremenek3f404602010-08-14 01:14:06 +00004462 // If the location of the cursor occurs within a macro instantiation, record
4463 // the spelling location of the cursor in our annotation map. We can then
4464 // paper over the token labelings during a post-processing step to try and
4465 // get cursor mappings for tokens that are the *arguments* of a macro
4466 // instantiation.
4467 if (L.isMacroID()) {
4468 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4469 // Only invalidate the old annotation if it isn't part of a preprocessing
4470 // directive. Here we assume that the default construction of CXCursor
4471 // results in CXCursor.kind being an initialized value (i.e., 0). If
4472 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregor4419b672010-10-21 06:10:04 +00004473
Ted Kremenek3f404602010-08-14 01:14:06 +00004474 CXCursor &oldC = Annotated[rawEncoding];
4475 if (!clang_isPreprocessing(oldC.kind))
4476 oldC = cursor;
4477 }
4478
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004479 const enum CXCursorKind K = clang_getCursorKind(parent);
4480 const CXCursor updateC =
Ted Kremenekd8b0a842010-08-25 22:16:02 +00004481 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4482 ? clang_getNullCursor() : parent;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004483
4484 while (MoreTokens()) {
4485 const unsigned I = NextToken();
4486 SourceLocation TokLoc = GetTokenLoc(I);
4487 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4488 case RangeBefore:
4489 Cursors[I] = updateC;
4490 AdvanceToken();
4491 continue;
4492 case RangeAfter:
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004493 case RangeOverlap:
4494 break;
4495 }
4496 break;
4497 }
4498
4499 // Visit children to get their cursor information.
4500 const unsigned BeforeChildren = NextToken();
4501 VisitChildren(cursor);
4502 const unsigned AfterChildren = NextToken();
4503
4504 // Adjust 'Last' to the last token within the extent of the cursor.
4505 while (MoreTokens()) {
4506 const unsigned I = NextToken();
4507 SourceLocation TokLoc = GetTokenLoc(I);
4508 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4509 case RangeBefore:
4510 assert(0 && "Infeasible");
4511 case RangeAfter:
4512 break;
4513 case RangeOverlap:
4514 Cursors[I] = updateC;
4515 AdvanceToken();
4516 continue;
4517 }
4518 break;
4519 }
4520 const unsigned Last = NextToken();
Ted Kremenek6db61092010-05-05 00:55:15 +00004521
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004522 // Scan the tokens that are at the beginning of the cursor, but are not
4523 // capture by the child cursors.
4524
4525 // For AST elements within macros, rely on a post-annotate pass to
4526 // to correctly annotate the tokens with cursors. Otherwise we can
4527 // get confusing results of having tokens that map to cursors that really
4528 // are expanded by an instantiation.
4529 if (L.isMacroID())
4530 cursor = clang_getNullCursor();
4531
4532 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4533 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4534 break;
Douglas Gregor4419b672010-10-21 06:10:04 +00004535
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004536 Cursors[I] = cursor;
4537 }
4538 // Scan the tokens that are at the end of the cursor, but are not captured
4539 // but the child cursors.
4540 for (unsigned I = AfterChildren; I != Last; ++I)
4541 Cursors[I] = cursor;
4542
4543 TokIdx = Last;
4544 return CXChildVisit_Continue;
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004545}
4546
Ted Kremenek6db61092010-05-05 00:55:15 +00004547static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4548 CXCursor parent,
4549 CXClientData client_data) {
4550 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4551}
4552
Ted Kremenekab979612010-11-11 08:05:23 +00004553// This gets run a separate thread to avoid stack blowout.
4554static void runAnnotateTokensWorker(void *UserData) {
4555 ((AnnotateTokensWorker*)UserData)->AnnotateTokens();
4556}
4557
Ted Kremenek6db61092010-05-05 00:55:15 +00004558extern "C" {
4559
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004560void clang_annotateTokens(CXTranslationUnit TU,
4561 CXToken *Tokens, unsigned NumTokens,
4562 CXCursor *Cursors) {
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004563
4564 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004565 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004566
Douglas Gregor4419b672010-10-21 06:10:04 +00004567 // Any token we don't specifically annotate will have a NULL cursor.
4568 CXCursor C = clang_getNullCursor();
4569 for (unsigned I = 0; I != NumTokens; ++I)
4570 Cursors[I] = C;
4571
Ted Kremeneka60ed472010-11-16 08:15:36 +00004572 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4419b672010-10-21 06:10:04 +00004573 if (!CXXUnit)
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004574 return;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004575
Douglas Gregorbdf60622010-03-05 21:16:25 +00004576 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004577
Douglas Gregor0396f462010-03-19 05:22:59 +00004578 // Determine the region of interest, which contains all of the tokens.
Douglas Gregor0045e9f2010-01-26 18:31:56 +00004579 SourceRange RegionOfInterest;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004580 RegionOfInterest.setBegin(cxloc::translateSourceLocation(
4581 clang_getTokenLocation(TU, Tokens[0])));
Douglas Gregora8e5c5b2010-07-22 20:22:31 +00004582 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
4583 clang_getTokenLocation(TU,
4584 Tokens[NumTokens - 1])));
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004585
Douglas Gregor0396f462010-03-19 05:22:59 +00004586 // A mapping from the source locations found when re-lexing or traversing the
4587 // region of interest to the corresponding cursors.
4588 AnnotateTokensData Annotated;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004589
4590 // Relex the tokens within the source range to look for preprocessing
Douglas Gregor0396f462010-03-19 05:22:59 +00004591 // directives.
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004592 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4593 std::pair<FileID, unsigned> BeginLocInfo
4594 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4595 std::pair<FileID, unsigned> EndLocInfo
4596 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004597
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004598 llvm::StringRef Buffer;
Douglas Gregor0396f462010-03-19 05:22:59 +00004599 bool Invalid = false;
4600 if (BeginLocInfo.first == EndLocInfo.first &&
4601 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4602 !Invalid) {
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004603 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4604 CXXUnit->getASTContext().getLangOptions(),
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004605 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
Douglas Gregor4ae8f292010-03-18 17:52:52 +00004606 Buffer.end());
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004607 Lex.SetCommentRetentionState(true);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004608
4609 // Lex tokens in raw mode until we hit the end of the range, to avoid
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004610 // entering #includes or expanding macros.
Douglas Gregor48072312010-03-18 15:23:44 +00004611 while (true) {
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004612 Token Tok;
4613 Lex.LexFromRawLexer(Tok);
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004614
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004615 reprocess:
4616 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4617 // We have found a preprocessing directive. Gobble it up so that we
Daniel Dunbar9e1ebdd2010-11-05 07:19:21 +00004618 // don't see it while preprocessing these tokens later, but keep track
4619 // of all of the token locations inside this preprocessing directive so
4620 // that we can annotate them appropriately.
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004621 //
4622 // FIXME: Some simple tests here could identify macro definitions and
4623 // #undefs, to provide specific cursor kinds for those.
4624 std::vector<SourceLocation> Locations;
4625 do {
4626 Locations.push_back(Tok.getLocation());
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004627 Lex.LexFromRawLexer(Tok);
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004628 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004629
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004630 using namespace cxcursor;
4631 CXCursor Cursor
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004632 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4633 Locations.back()),
Ted Kremeneka60ed472010-11-16 08:15:36 +00004634 TU);
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004635 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4636 Annotated[Locations[I].getRawEncoding()] = Cursor;
4637 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004638
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004639 if (Tok.isAtStartOfLine())
4640 goto reprocess;
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004641
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004642 continue;
4643 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004644
Douglas Gregor48072312010-03-18 15:23:44 +00004645 if (Tok.is(tok::eof))
Douglas Gregor9f1e3ff2010-03-18 00:42:48 +00004646 break;
4647 }
Douglas Gregor4ae8f292010-03-18 17:52:52 +00004648 }
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004649
Douglas Gregor0396f462010-03-19 05:22:59 +00004650 // Annotate all of the source locations in the region of interest that map to
Ted Kremenekfbd84ca2010-05-05 00:55:23 +00004651 // a specific cursor.
4652 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
Ted Kremeneka60ed472010-11-16 08:15:36 +00004653 TU, RegionOfInterest);
Ted Kremenekab979612010-11-11 08:05:23 +00004654
4655 // Run the worker within a CrashRecoveryContext.
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004656 // FIXME: We use a ridiculous stack size here because the data-recursion
4657 // algorithm uses a large stack frame than the non-data recursive version,
4658 // and AnnotationTokensWorker currently transforms the data-recursion
4659 // algorithm back into a traditional recursion by explicitly calling
4660 // VisitChildren(). We will need to remove this explicit recursive call.
Ted Kremenekab979612010-11-11 08:05:23 +00004661 llvm::CrashRecoveryContext CRC;
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00004662 if (!RunSafely(CRC, runAnnotateTokensWorker, &W,
4663 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekab979612010-11-11 08:05:23 +00004664 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4665 }
Douglas Gregorf5251602011-03-08 17:10:18 +00004666
4667 // If we ran into any entities that involve context-sensitive keywords,
4668 // take another pass through the tokens to mark them as such.
4669 if (W.hasContextSensitiveKeywords()) {
4670 for (unsigned I = 0; I != NumTokens; ++I) {
4671 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4672 continue;
4673
4674 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4675 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4676 if (ObjCPropertyDecl *Property
4677 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4678 if (Property->getPropertyAttributesAsWritten() != 0 &&
4679 llvm::StringSwitch<bool>(II->getName())
4680 .Case("readonly", true)
4681 .Case("assign", true)
4682 .Case("readwrite", true)
4683 .Case("retain", true)
4684 .Case("copy", true)
4685 .Case("nonatomic", true)
4686 .Case("atomic", true)
4687 .Case("getter", true)
4688 .Case("setter", true)
4689 .Default(false))
4690 Tokens[I].int_data[0] = CXToken_Keyword;
4691 }
4692 continue;
4693 }
4694
4695 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4696 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4697 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4698 if (llvm::StringSwitch<bool>(II->getName())
4699 .Case("in", true)
4700 .Case("out", true)
4701 .Case("inout", true)
4702 .Case("oneway", true)
4703 .Case("bycopy", true)
4704 .Case("byref", true)
4705 .Default(false))
4706 Tokens[I].int_data[0] = CXToken_Keyword;
4707 continue;
4708 }
4709
4710 if (Cursors[I].kind == CXCursor_CXXMethod) {
4711 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4712 if (CXXMethodDecl *Method
4713 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4714 if ((Method->hasAttr<FinalAttr>() ||
4715 Method->hasAttr<OverrideAttr>()) &&
4716 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4717 llvm::StringSwitch<bool>(II->getName())
4718 .Case("final", true)
4719 .Case("override", true)
4720 .Default(false))
4721 Tokens[I].int_data[0] = CXToken_Keyword;
4722 }
4723 continue;
4724 }
4725
4726 if (Cursors[I].kind == CXCursor_ClassDecl ||
4727 Cursors[I].kind == CXCursor_StructDecl ||
4728 Cursors[I].kind == CXCursor_ClassTemplate) {
4729 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4730 if (II->getName() == "final") {
4731 // We have to be careful with 'final', since it could be the name
4732 // of a member class rather than the context-sensitive keyword.
4733 // So, check whether the cursor associated with this
4734 Decl *D = getCursorDecl(Cursors[I]);
4735 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4736 if ((Record->hasAttr<FinalAttr>()) &&
4737 Record->getIdentifier() != II)
4738 Tokens[I].int_data[0] = CXToken_Keyword;
4739 } else if (ClassTemplateDecl *ClassTemplate
4740 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4741 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4742 if ((Record->hasAttr<FinalAttr>()) &&
4743 Record->getIdentifier() != II)
4744 Tokens[I].int_data[0] = CXToken_Keyword;
4745 }
4746 }
4747 continue;
4748 }
4749 }
4750 }
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004751}
Douglas Gregorfc8ea232010-01-26 17:06:03 +00004752} // end: extern "C"
4753
4754//===----------------------------------------------------------------------===//
Ted Kremenek16b42592010-03-03 06:36:57 +00004755// Operations for querying linkage of a cursor.
4756//===----------------------------------------------------------------------===//
4757
4758extern "C" {
4759CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor0396f462010-03-19 05:22:59 +00004760 if (!clang_isDeclaration(cursor.kind))
4761 return CXLinkage_Invalid;
4762
Ted Kremenek16b42592010-03-03 06:36:57 +00004763 Decl *D = cxcursor::getCursorDecl(cursor);
4764 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4765 switch (ND->getLinkage()) {
4766 case NoLinkage: return CXLinkage_NoLinkage;
4767 case InternalLinkage: return CXLinkage_Internal;
4768 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4769 case ExternalLinkage: return CXLinkage_External;
4770 };
4771
4772 return CXLinkage_Invalid;
4773}
4774} // end: extern "C"
4775
4776//===----------------------------------------------------------------------===//
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004777// Operations for querying language of a cursor.
4778//===----------------------------------------------------------------------===//
4779
4780static CXLanguageKind getDeclLanguage(const Decl *D) {
4781 switch (D->getKind()) {
4782 default:
4783 break;
4784 case Decl::ImplicitParam:
4785 case Decl::ObjCAtDefsField:
4786 case Decl::ObjCCategory:
4787 case Decl::ObjCCategoryImpl:
4788 case Decl::ObjCClass:
4789 case Decl::ObjCCompatibleAlias:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004790 case Decl::ObjCForwardProtocol:
4791 case Decl::ObjCImplementation:
4792 case Decl::ObjCInterface:
4793 case Decl::ObjCIvar:
4794 case Decl::ObjCMethod:
4795 case Decl::ObjCProperty:
4796 case Decl::ObjCPropertyImpl:
4797 case Decl::ObjCProtocol:
4798 return CXLanguage_ObjC;
4799 case Decl::CXXConstructor:
4800 case Decl::CXXConversion:
4801 case Decl::CXXDestructor:
4802 case Decl::CXXMethod:
4803 case Decl::CXXRecord:
4804 case Decl::ClassTemplate:
4805 case Decl::ClassTemplatePartialSpecialization:
4806 case Decl::ClassTemplateSpecialization:
4807 case Decl::Friend:
4808 case Decl::FriendTemplate:
4809 case Decl::FunctionTemplate:
4810 case Decl::LinkageSpec:
4811 case Decl::Namespace:
4812 case Decl::NamespaceAlias:
4813 case Decl::NonTypeTemplateParm:
4814 case Decl::StaticAssert:
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004815 case Decl::TemplateTemplateParm:
4816 case Decl::TemplateTypeParm:
4817 case Decl::UnresolvedUsingTypename:
4818 case Decl::UnresolvedUsingValue:
4819 case Decl::Using:
4820 case Decl::UsingDirective:
4821 case Decl::UsingShadow:
4822 return CXLanguage_CPlusPlus;
4823 }
4824
4825 return CXLanguage_C;
4826}
4827
4828extern "C" {
Douglas Gregor58ddb602010-08-23 23:00:57 +00004829
4830enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4831 if (clang_isDeclaration(cursor.kind))
4832 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
4833 if (D->hasAttr<UnavailableAttr>() ||
4834 (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()))
4835 return CXAvailability_Available;
4836
4837 if (D->hasAttr<DeprecatedAttr>())
4838 return CXAvailability_Deprecated;
4839 }
4840
4841 return CXAvailability_Available;
4842}
4843
Ted Kremenek45e1dae2010-04-12 21:22:16 +00004844CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4845 if (clang_isDeclaration(cursor.kind))
4846 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4847
4848 return CXLanguage_Invalid;
4849}
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004850
4851 /// \brief If the given cursor is the "templated" declaration
4852 /// descibing a class or function template, return the class or
4853 /// function template.
4854static Decl *maybeGetTemplateCursor(Decl *D) {
4855 if (!D)
4856 return 0;
4857
4858 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4859 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4860 return FunTmpl;
4861
4862 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4863 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4864 return ClassTmpl;
4865
4866 return D;
4867}
4868
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004869CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4870 if (clang_isDeclaration(cursor.kind)) {
4871 if (Decl *D = getCursorDecl(cursor)) {
4872 DeclContext *DC = D->getDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004873 if (!DC)
4874 return clang_getNullCursor();
4875
4876 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4877 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004878 }
4879 }
4880
4881 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4882 if (Decl *D = getCursorDecl(cursor))
Ted Kremeneka60ed472010-11-16 08:15:36 +00004883 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004884 }
4885
4886 return clang_getNullCursor();
4887}
4888
4889CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4890 if (clang_isDeclaration(cursor.kind)) {
4891 if (Decl *D = getCursorDecl(cursor)) {
4892 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor3910cfd2010-12-21 07:55:45 +00004893 if (!DC)
4894 return clang_getNullCursor();
4895
4896 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4897 getCursorTU(cursor));
Douglas Gregor2be5bc92010-09-22 21:22:29 +00004898 }
4899 }
4900
4901 // FIXME: Note that we can't easily compute the lexical context of a
4902 // statement or expression, so we return nothing.
4903 return clang_getNullCursor();
4904}
4905
Douglas Gregor9f592342010-10-01 20:25:15 +00004906static void CollectOverriddenMethods(DeclContext *Ctx,
4907 ObjCMethodDecl *Method,
4908 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
4909 if (!Ctx)
4910 return;
4911
4912 // If we have a class or category implementation, jump straight to the
4913 // interface.
4914 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
4915 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
4916
4917 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
4918 if (!Container)
4919 return;
4920
4921 // Check whether we have a matching method at this level.
4922 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
4923 Method->isInstanceMethod()))
4924 if (Method != Overridden) {
4925 // We found an override at this level; there is no need to look
4926 // into other protocols or categories.
4927 Methods.push_back(Overridden);
4928 return;
4929 }
4930
4931 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4932 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
4933 PEnd = Protocol->protocol_end();
4934 P != PEnd; ++P)
4935 CollectOverriddenMethods(*P, Method, Methods);
4936 }
4937
4938 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4939 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
4940 PEnd = Category->protocol_end();
4941 P != PEnd; ++P)
4942 CollectOverriddenMethods(*P, Method, Methods);
4943 }
4944
4945 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
4946 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
4947 PEnd = Interface->protocol_end();
4948 P != PEnd; ++P)
4949 CollectOverriddenMethods(*P, Method, Methods);
4950
4951 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
4952 Category; Category = Category->getNextClassCategory())
4953 CollectOverriddenMethods(Category, Method, Methods);
4954
4955 // We only look into the superclass if we haven't found anything yet.
4956 if (Methods.empty())
4957 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
4958 return CollectOverriddenMethods(Super, Method, Methods);
4959 }
4960}
4961
4962void clang_getOverriddenCursors(CXCursor cursor,
4963 CXCursor **overridden,
4964 unsigned *num_overridden) {
4965 if (overridden)
4966 *overridden = 0;
4967 if (num_overridden)
4968 *num_overridden = 0;
4969 if (!overridden || !num_overridden)
4970 return;
4971
4972 if (!clang_isDeclaration(cursor.kind))
4973 return;
4974
4975 Decl *D = getCursorDecl(cursor);
4976 if (!D)
4977 return;
4978
4979 // Handle C++ member functions.
Ted Kremeneka60ed472010-11-16 08:15:36 +00004980 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor9f592342010-10-01 20:25:15 +00004981 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
4982 *num_overridden = CXXMethod->size_overridden_methods();
4983 if (!*num_overridden)
4984 return;
4985
4986 *overridden = new CXCursor [*num_overridden];
4987 unsigned I = 0;
4988 for (CXXMethodDecl::method_iterator
4989 M = CXXMethod->begin_overridden_methods(),
4990 MEnd = CXXMethod->end_overridden_methods();
4991 M != MEnd; (void)++M, ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00004992 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00004993 return;
4994 }
4995
4996 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
4997 if (!Method)
4998 return;
4999
5000 // Handle Objective-C methods.
5001 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5002 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5003
5004 if (Methods.empty())
5005 return;
5006
5007 *num_overridden = Methods.size();
5008 *overridden = new CXCursor [Methods.size()];
5009 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005010 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor9f592342010-10-01 20:25:15 +00005011}
5012
5013void clang_disposeOverriddenCursors(CXCursor *overridden) {
5014 delete [] overridden;
5015}
5016
Douglas Gregorecdcb882010-10-20 22:00:55 +00005017CXFile clang_getIncludedFile(CXCursor cursor) {
5018 if (cursor.kind != CXCursor_InclusionDirective)
5019 return 0;
5020
5021 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5022 return (void *)ID->getFile();
5023}
5024
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005025} // end: extern "C"
5026
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005027
5028//===----------------------------------------------------------------------===//
5029// C++ AST instrospection.
5030//===----------------------------------------------------------------------===//
5031
5032extern "C" {
5033unsigned clang_CXXMethod_isStatic(CXCursor C) {
5034 if (!clang_isDeclaration(C.kind))
5035 return 0;
Douglas Gregor49f6f542010-08-31 22:12:17 +00005036
5037 CXXMethodDecl *Method = 0;
5038 Decl *D = cxcursor::getCursorDecl(C);
5039 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5040 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5041 else
5042 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5043 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek40b492a2010-05-17 20:12:45 +00005044}
Ted Kremenekb12903e2010-05-18 22:32:15 +00005045
Ted Kremenek9ada39a2010-05-17 20:06:56 +00005046} // end: extern "C"
5047
Ted Kremenek45e1dae2010-04-12 21:22:16 +00005048//===----------------------------------------------------------------------===//
Ted Kremenek95f33552010-08-26 01:42:22 +00005049// Attribute introspection.
5050//===----------------------------------------------------------------------===//
5051
5052extern "C" {
5053CXType clang_getIBOutletCollectionType(CXCursor C) {
5054 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremeneka60ed472010-11-16 08:15:36 +00005055 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005056
5057 IBOutletCollectionAttr *A =
5058 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5059
Douglas Gregor841b2382011-03-06 18:55:32 +00005060 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremenek95f33552010-08-26 01:42:22 +00005061}
5062} // end: extern "C"
5063
5064//===----------------------------------------------------------------------===//
Ted Kremenek04bb7162010-01-22 22:44:15 +00005065// Misc. utility functions.
5066//===----------------------------------------------------------------------===//
Ted Kremenekf0e23e82010-02-17 00:41:40 +00005067
Daniel Dunbarabdce7a2010-11-05 17:21:46 +00005068/// Default to using an 8 MB stack size on "safety" threads.
5069static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005070
5071namespace clang {
5072
5073bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenek6c53fdd2010-11-14 17:47:35 +00005074 void (*Fn)(void*), void *UserData,
5075 unsigned Size) {
5076 if (!Size)
5077 Size = GetSafetyThreadStackSize();
5078 if (Size)
Daniel Dunbarbf44c3b2010-11-05 07:19:31 +00005079 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5080 return CRC.RunSafely(Fn, UserData);
5081}
5082
5083unsigned GetSafetyThreadStackSize() {
5084 return SafetyStackThreadSize;
5085}
5086
5087void SetSafetyThreadStackSize(unsigned Value) {
5088 SafetyStackThreadSize = Value;
5089}
5090
5091}
5092
Ted Kremenek04bb7162010-01-22 22:44:15 +00005093extern "C" {
5094
Ted Kremeneka2a9d6e2010-02-12 22:54:40 +00005095CXString clang_getClangVersion() {
Ted Kremenekee4db4f2010-02-17 00:41:08 +00005096 return createCXString(getClangFullVersion());
Ted Kremenek04bb7162010-01-22 22:44:15 +00005097}
5098
5099} // end: extern "C"