blob: 0978f1b2813854dc90fa115b2751abcd10988aa8 [file] [log] [blame]
Ted Kremenekb60d87c2009-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 Dunbarbbc569c2009-11-30 20:42:43 +00007//
Ted Kremenekb60d87c2009-08-26 22:36:44 +00008//===----------------------------------------------------------------------===//
9//
Ted Kremenek0ec2cca2010-01-05 19:32:54 +000010// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
Ted Kremenekb60d87c2009-08-26 22:36:44 +000012//
13//===----------------------------------------------------------------------===//
14
Ted Kremenek0ec2cca2010-01-05 19:32:54 +000015#include "CIndexer.h"
Ted Kremenek87553c42010-01-15 20:35:54 +000016#include "CXCursor.h"
Ted Kremenek7df92ae2010-11-17 23:24:11 +000017#include "CXTranslationUnit.h"
Ted Kremenek4b4f3692010-11-16 01:56:27 +000018#include "CXString.h"
Ted Kremeneka5940822010-08-26 01:42:22 +000019#include "CXType.h"
Ted Kremenek97a45372010-01-25 22:34:44 +000020#include "CXSourceLocation.h"
Douglas Gregor4f9c3762010-01-28 00:27:43 +000021#include "CIndexDiagnostic.h"
Ted Kremenek0ec2cca2010-01-05 19:32:54 +000022
Ted Kremenekc0f3f722010-01-22 22:44:15 +000023#include "clang/Basic/Version.h"
Douglas Gregorba965fb2010-01-28 00:56:43 +000024
Steve Naroffa1c72842009-08-28 15:28:48 +000025#include "clang/AST/DeclVisitor.h"
Steve Naroff66af1ae2009-09-22 19:25:29 +000026#include "clang/AST/StmtVisitor.h"
Douglas Gregor93f89952010-01-21 16:28:34 +000027#include "clang/AST/TypeLocVisitor.h"
Benjamin Kramer064414532010-04-12 19:45:50 +000028#include "clang/Basic/Diagnostic.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
Douglas Gregorba965fb2010-01-28 00:56:43 +000031#include "clang/Frontend/FrontendDiagnostic.h"
Ted Kremenek2a43fd52010-01-06 23:43:31 +000032#include "clang/Lex/Lexer.h"
Benjamin Kramer064414532010-04-12 19:45:50 +000033#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregor562c1f92010-01-22 19:49:59 +000034#include "clang/Lex/Preprocessor.h"
Douglas Gregorf3af3112010-09-09 21:42:20 +000035#include "llvm/ADT/STLExtras.h"
Ted Kremenekd40a4392010-11-02 23:10:24 +000036#include "llvm/ADT/Optional.h"
Douglas Gregorf2f08062011-03-08 17:10:18 +000037#include "llvm/ADT/StringSwitch.h"
Ted Kremenekd40a4392010-11-02 23:10:24 +000038#include "clang/Analysis/Support/SaveAndRestore.h"
Daniel Dunbarc91f2ff2010-08-18 18:43:14 +000039#include "llvm/Support/CrashRecoveryContext.h"
Daniel Dunbara5af410d2010-10-08 19:30:33 +000040#include "llvm/Support/PrettyStackTrace.h"
Douglas Gregord3d923a2009-10-16 21:24:31 +000041#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor97c75712010-10-02 22:49:11 +000042#include "llvm/Support/raw_ostream.h"
Douglas Gregor8ef4c802010-08-09 21:00:09 +000043#include "llvm/Support/Timer.h"
Michael J. Spencer8aaf4992010-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 Kremenekacd03f62010-11-15 23:11:54 +000048#include "llvm/Support/Compiler.h"
Ted Kremenek428c6372009-10-19 21:44:57 +000049
Steve Naroffa1c72842009-08-28 15:28:48 +000050using namespace clang;
Ted Kremenek87553c42010-01-15 20:35:54 +000051using namespace clang::cxcursor;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +000052using namespace clang::cxstring;
Steve Naroffa1c72842009-08-28 15:28:48 +000053
Ted Kremenek91554282010-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 Gregor562c1f92010-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 Kremenekf441baf2010-02-17 00:41:40 +000067
Douglas Gregor562c1f92010-01-22 19:49:59 +000068 /// \brief The first range ends before the second range starts.
69 RangeBefore,
Ted Kremenekf441baf2010-02-17 00:41:40 +000070
Douglas Gregor562c1f92010-01-22 19:49:59 +000071 /// \brief The first range starts after the second range ends.
72 RangeAfter
73};
74
Ted Kremenekf441baf2010-02-17 00:41:40 +000075/// \brief Compare two source ranges to determine their relative position in
Douglas Gregor562c1f92010-01-22 19:49:59 +000076/// the translation unit.
Ted Kremenekf441baf2010-02-17 00:41:40 +000077static RangeComparisonResult RangeCompare(SourceManager &SM,
78 SourceRange R1,
Douglas Gregor562c1f92010-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 Gregorcd8bdd02010-07-22 20:22:31 +000082 if (R1.getEnd() != R2.getBegin() &&
Daniel Dunbar02968e52010-02-14 10:02:57 +000083 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
Douglas Gregor562c1f92010-01-22 19:49:59 +000084 return RangeBefore;
Douglas Gregorcd8bdd02010-07-22 20:22:31 +000085 if (R2.getEnd() != R1.getBegin() &&
Daniel Dunbar02968e52010-02-14 10:02:57 +000086 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
Douglas Gregor562c1f92010-01-22 19:49:59 +000087 return RangeAfter;
88 return RangeOverlap;
89}
90
Ted Kremenek680fe512010-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 Gregorcd8bdd02010-07-22 20:22:31 +000097 if (L == R.getBegin() || L == R.getEnd())
Ted Kremenek680fe512010-05-05 00:55:23 +000098 return RangeOverlap;
Ted Kremenek680fe512010-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 Dunbar474b2072010-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 Kremenekf441baf2010-02-17 00:41:40 +0000112CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
Daniel Dunbar474b2072010-02-14 01:47:29 +0000113 const LangOptions &LangOpts,
Chris Lattnered8b6b72010-06-18 22:45:06 +0000114 const CharSourceRange &R) {
Daniel Dunbar474b2072010-02-14 01:47:29 +0000115 // We want the last character in this location, so we will adjust the
Douglas Gregoraae92242010-03-19 21:51:54 +0000116 // location accordingly.
Daniel Dunbar474b2072010-02-14 01:47:29 +0000117 SourceLocation EndLoc = R.getEnd();
Douglas Gregor229bebd2010-11-09 06:24:54 +0000118 if (EndLoc.isValid() && EndLoc.isMacroID())
119 EndLoc = SM.getSpellingLoc(EndLoc);
Chris Lattnered8b6b72010-06-18 22:45:06 +0000120 if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
Douglas Gregoraae92242010-03-19 21:51:54 +0000121 unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
Daniel Dunbar474b2072010-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 Gregor4f46e782010-01-19 21:36:55 +0000130
Ted Kremenek991eb3f2010-01-06 03:42:32 +0000131//===----------------------------------------------------------------------===//
Douglas Gregor562c1f92010-01-22 19:49:59 +0000132// Cursor visitor.
Ted Kremenek991eb3f2010-01-06 03:42:32 +0000133//===----------------------------------------------------------------------===//
134
Steve Naroff1054e602009-08-31 00:59:03 +0000135namespace {
Ted Kremenek92209a42010-11-11 08:05:18 +0000136
137class VisitorJob {
138public:
Ted Kremeneke12bcf52010-11-12 21:34:12 +0000139 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
Ted Kremenek573411b2010-11-13 00:58:18 +0000140 TypeLocVisitKind, OverloadExprPartsKind,
Ted Kremenek8eaa1652010-11-17 00:50:47 +0000141 DeclRefExprPartsKind, LabelRefVisitKind,
Ted Kremenek83900272010-11-18 00:02:32 +0000142 ExplicitTemplateArgsVisitKind,
143 NestedNameSpecifierVisitKind,
Douglas Gregora6ce6082011-02-25 18:19:59 +0000144 NestedNameSpecifierLocVisitKind,
Ted Kremenek5d304a32010-11-18 00:42:18 +0000145 DeclarationNameInfoVisitKind,
Douglas Gregor557f05c2011-01-19 20:34:17 +0000146 MemberRefVisitKind, SizeOfPackExprPartsKind };
Ted Kremenek92209a42010-11-11 08:05:18 +0000147protected:
Ted Kremenek83900272010-11-18 00:02:32 +0000148 void *data[3];
Ted Kremenek92209a42010-11-11 08:05:18 +0000149 CXCursor parent;
150 Kind K;
Ted Kremenek83900272010-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 Kremenek92209a42010-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 Gregor71f3d942010-01-20 20:59:29 +0000165// Cursor visitor.
Douglas Gregor93f89952010-01-21 16:28:34 +0000166class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
Ted Kremenek5d304a32010-11-18 00:42:18 +0000167 public TypeLocVisitor<CursorVisitor, bool>
Douglas Gregor93f89952010-01-21 16:28:34 +0000168{
Douglas Gregor562c1f92010-01-22 19:49:59 +0000169 /// \brief The translation unit we are traversing.
Ted Kremenek91554282010-11-16 08:15:36 +0000170 CXTranslationUnit TU;
171 ASTUnit *AU;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000172
Douglas Gregor562c1f92010-01-22 19:49:59 +0000173 /// \brief The parent cursor whose children we are traversing.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000174 CXCursor Parent;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000175
Douglas Gregor562c1f92010-01-22 19:49:59 +0000176 /// \brief The declaration that serves at the parent of any statement or
177 /// expression nodes.
Douglas Gregord1824312010-01-21 17:29:07 +0000178 Decl *StmtParent;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000179
Douglas Gregor562c1f92010-01-22 19:49:59 +0000180 /// \brief The visitor function.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000181 CXCursorVisitor Visitor;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000182
Douglas Gregor562c1f92010-01-22 19:49:59 +0000183 /// \brief The opaque client data, to be passed along to the visitor.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000184 CXClientData ClientData;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000185
Douglas Gregor16bef852009-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 Gregor562c1f92010-01-22 19:49:59 +0000190
Douglas Gregorc2b97992011-03-16 23:23:30 +0000191 /// \brief Whether we should visit the preprocessing record entries last,
192 /// after visiting other declarations.
193 bool VisitPreprocessorLast;
194
Douglas Gregor562c1f92010-01-22 19:49:59 +0000195 /// \brief When valid, a source range to which the cursor should restrict
196 /// its search.
197 SourceRange RegionOfInterest;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000198
Ted Kremenekd40a4392010-11-02 23:10:24 +0000199 // FIXME: Eventually remove. This part of a hack to support proper
200 // iteration over all Decls contained lexically within an ObjC container.
201 DeclContext::decl_iterator *DI_current;
202 DeclContext::decl_iterator DE_current;
203
Ted Kremeneka4c27ec2010-11-15 23:31:32 +0000204 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
205 llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
206 llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
207
Douglas Gregor71f3d942010-01-20 20:59:29 +0000208 using DeclVisitor<CursorVisitor, bool>::Visit;
Douglas Gregor93f89952010-01-21 16:28:34 +0000209 using TypeLocVisitor<CursorVisitor, bool>::Visit;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000210
211 /// \brief Determine whether this particular source range comes before, comes
212 /// after, or overlaps the region of interest.
Douglas Gregor562c1f92010-01-22 19:49:59 +0000213 ///
Daniel Dunbar02968e52010-02-14 10:02:57 +0000214 /// \param R a half-open source range retrieved from the abstract syntax tree.
Ted Kremenekf441baf2010-02-17 00:41:40 +0000215 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
216
Ted Kremenek12e0f292010-05-13 00:25:00 +0000217 class SetParentRAII {
218 CXCursor &Parent;
219 Decl *&StmtParent;
220 CXCursor OldParent;
221
222 public:
223 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
224 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
225 {
226 Parent = NewParent;
227 if (clang_isDeclaration(Parent.kind))
228 StmtParent = getCursorDecl(Parent);
229 }
230
231 ~SetParentRAII() {
232 Parent = OldParent;
233 if (clang_isDeclaration(Parent.kind))
234 StmtParent = getCursorDecl(Parent);
235 }
236 };
237
Steve Naroff1054e602009-08-31 00:59:03 +0000238public:
Ted Kremenek91554282010-11-16 08:15:36 +0000239 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
240 CXClientData ClientData,
Ted Kremenekf441baf2010-02-17 00:41:40 +0000241 unsigned MaxPCHLevel,
Douglas Gregorc2b97992011-03-16 23:23:30 +0000242 bool VisitPreprocessorLast,
Douglas Gregor562c1f92010-01-22 19:49:59 +0000243 SourceRange RegionOfInterest = SourceRange())
Ted Kremenek91554282010-11-16 08:15:36 +0000244 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
245 Visitor(Visitor), ClientData(ClientData),
Douglas Gregorc2b97992011-03-16 23:23:30 +0000246 MaxPCHLevel(MaxPCHLevel), VisitPreprocessorLast(VisitPreprocessorLast),
247 RegionOfInterest(RegionOfInterest), DI_current(0)
Douglas Gregor71f3d942010-01-20 20:59:29 +0000248 {
249 Parent.kind = CXCursor_NoDeclFound;
250 Parent.data[0] = 0;
251 Parent.data[1] = 0;
252 Parent.data[2] = 0;
Douglas Gregord1824312010-01-21 17:29:07 +0000253 StmtParent = 0;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000254 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000255
Ted Kremeneka4c27ec2010-11-15 23:31:32 +0000256 ~CursorVisitor() {
257 // Free the pre-allocated worklists for data-recursion.
258 for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
259 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
260 delete *I;
261 }
262 }
263
Ted Kremenek91554282010-11-16 08:15:36 +0000264 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
265 CXTranslationUnit getTU() const { return TU; }
Ted Kremenekc7a5bae2010-11-11 08:05:23 +0000266
Douglas Gregor562c1f92010-01-22 19:49:59 +0000267 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000268
269 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
270 getPreprocessedEntities();
271
Douglas Gregor71f3d942010-01-20 20:59:29 +0000272 bool VisitChildren(CXCursor Parent);
Ted Kremenekf441baf2010-02-17 00:41:40 +0000273
Douglas Gregor93f89952010-01-21 16:28:34 +0000274 // Declaration visitors
Ted Kremenek6ab9aa022010-02-18 05:46:33 +0000275 bool VisitAttributes(Decl *D);
Ted Kremenek33b9a422010-04-11 21:47:37 +0000276 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenekae9e2212010-08-27 21:34:58 +0000277 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd40a4392010-11-02 23:10:24 +0000278 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregor71f3d942010-01-20 20:59:29 +0000279 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek7dff4162010-02-18 18:47:08 +0000280 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
281 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000282 bool VisitTagDecl(TagDecl *D);
Douglas Gregor9dc243c2010-09-01 17:32:36 +0000283 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregorf96abb22010-08-31 19:31:58 +0000284 bool VisitClassTemplatePartialSpecializationDecl(
285 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregor713602b2010-08-31 17:01:39 +0000286 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000287 bool VisitEnumConstantDecl(EnumConstantDecl *D);
288 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
289 bool VisitFunctionDecl(FunctionDecl *ND);
290 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek7dff4162010-02-18 18:47:08 +0000291 bool VisitVarDecl(VarDecl *);
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000292 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregor713602b2010-08-31 17:01:39 +0000293 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor1fbaeb12010-08-31 19:02:00 +0000294 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000295 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000296 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
297 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
298 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
299 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek49be9e02010-05-18 21:09:07 +0000300 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremeneke2110252010-02-18 22:36:18 +0000301 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
302 bool VisitObjCImplDecl(ObjCImplDecl *D);
303 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
304 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000305 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
306 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
307 bool VisitObjCClassDecl(ObjCClassDecl *D);
Douglas Gregorb1b71e52010-11-17 01:03:52 +0000308 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
Ted Kremenekb80cba52010-05-07 01:04:29 +0000309 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenekbd67fb22010-05-06 23:38:21 +0000310 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregora89314e2010-08-31 23:48:11 +0000311 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor01a430132010-09-01 03:07:18 +0000312 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregora9aa29c2010-09-01 19:52:22 +0000313 bool VisitUsingDecl(UsingDecl *D);
314 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
315 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor01a430132010-09-01 03:07:18 +0000316
Douglas Gregor12bca222010-08-31 14:41:23 +0000317 // Name visitor
318 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregor3335f482010-09-02 17:35:32 +0000319 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregora9d87bc2011-02-25 00:36:19 +0000320 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
Douglas Gregor12bca222010-08-31 14:41:23 +0000321
Douglas Gregor713602b2010-08-31 17:01:39 +0000322 // Template visitors
323 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregora23e8f72010-08-31 20:37:03 +0000324 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregor713602b2010-08-31 17:01:39 +0000325 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
326
Douglas Gregor93f89952010-01-21 16:28:34 +0000327 // Type visitors
Douglas Gregor12bca222010-08-31 14:41:23 +0000328 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000329 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor93f89952010-01-21 16:28:34 +0000330 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000331 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
332 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregor713602b2010-08-31 17:01:39 +0000333 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000334 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCall8b07ec22010-05-15 11:32:37 +0000335 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000336 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
Abramo Bagnara924a8f32010-12-10 16:29:40 +0000337 bool VisitParenTypeLoc(ParenTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000338 bool VisitPointerTypeLoc(PointerTypeLoc TL);
339 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
340 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
341 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
342 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor12bca222010-08-31 14:41:23 +0000343 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregord1824312010-01-21 17:29:07 +0000344 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregor713602b2010-08-31 17:01:39 +0000345 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor6479fc42010-01-21 20:48:56 +0000346 // FIXME: Implement visitors here when the unimplemented TypeLocs get
347 // implemented
348 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
Douglas Gregord2fa7662010-12-20 02:24:11 +0000349 bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
Douglas Gregor6479fc42010-01-21 20:48:56 +0000350 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Douglas Gregor3d0da5f2011-03-01 01:34:45 +0000351 bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
Douglas Gregora7a795b2011-03-01 20:11:18 +0000352 bool VisitDependentTemplateSpecializationTypeLoc(
353 DependentTemplateSpecializationTypeLoc TL);
Douglas Gregor844cb502011-03-01 18:12:44 +0000354 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
Douglas Gregor3d0da5f2011-03-01 01:34:45 +0000355
Ted Kremenek92209a42010-11-11 08:05:18 +0000356 // Data-recursive visitor functions.
357 bool IsInRegionOfInterest(CXCursor C);
358 bool RunVisitorWorkList(VisitorWorkList &WL);
359 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
Ted Kremenek5d304a32010-11-18 00:42:18 +0000360 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
Steve Naroff1054e602009-08-31 00:59:03 +0000361};
Ted Kremenekf441baf2010-02-17 00:41:40 +0000362
Ted Kremenek0ec2cca2010-01-05 19:32:54 +0000363} // end anonymous namespace
Benjamin Kramer61f5d0c2009-10-18 16:11:04 +0000364
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000365static SourceRange getRawCursorExtent(CXCursor C);
Douglas Gregor29ee4222010-11-17 17:14:07 +0000366static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
367
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000368
Douglas Gregor562c1f92010-01-22 19:49:59 +0000369RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Ted Kremenek91554282010-11-16 08:15:36 +0000370 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
Douglas Gregor562c1f92010-01-22 19:49:59 +0000371}
372
Douglas Gregor71f3d942010-01-20 20:59:29 +0000373/// \brief Visit the given cursor and, if requested by the visitor,
374/// its children.
375///
Douglas Gregor562c1f92010-01-22 19:49:59 +0000376/// \param Cursor the cursor to visit.
377///
378/// \param CheckRegionOfInterest if true, then the caller already checked that
379/// this cursor is within the region of interest.
380///
Douglas Gregor71f3d942010-01-20 20:59:29 +0000381/// \returns true if the visitation should be aborted, false if it
382/// should continue.
Douglas Gregor562c1f92010-01-22 19:49:59 +0000383bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregor71f3d942010-01-20 20:59:29 +0000384 if (clang_isInvalid(Cursor.kind))
385 return false;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000386
Douglas Gregor71f3d942010-01-20 20:59:29 +0000387 if (clang_isDeclaration(Cursor.kind)) {
388 Decl *D = getCursorDecl(Cursor);
389 assert(D && "Invalid declaration cursor");
390 if (D->getPCHLevel() > MaxPCHLevel)
391 return false;
392
393 if (D->isImplicit())
394 return false;
395 }
396
Douglas Gregor562c1f92010-01-22 19:49:59 +0000397 // If we have a range of interest, and this cursor doesn't intersect with it,
398 // we're done.
399 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000400 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbar2f4ba172010-02-14 08:32:05 +0000401 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor562c1f92010-01-22 19:49:59 +0000402 return false;
403 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000404
Douglas Gregor71f3d942010-01-20 20:59:29 +0000405 switch (Visitor(Cursor, Parent, ClientData)) {
406 case CXChildVisit_Break:
407 return true;
408
409 case CXChildVisit_Continue:
410 return false;
411
412 case CXChildVisit_Recurse:
413 return VisitChildren(Cursor);
414 }
415
Douglas Gregor33f16852010-01-25 16:45:46 +0000416 return false;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000417}
418
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000419std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
420CursorVisitor::getPreprocessedEntities() {
421 PreprocessingRecord &PPRec
Ted Kremenek91554282010-11-16 08:15:36 +0000422 = *AU->getPreprocessor().getPreprocessingRecord();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000423
424 bool OnlyLocalDecls
Douglas Gregorfd4da712010-12-21 19:07:48 +0000425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls && RegionOfInterest.isValid()) {
428 // If we would only look at local declarations but we have a region of
429 // interest, check whether that region of interest is in the main file.
430 // If not, we should traverse all declarations.
431 // FIXME: My kingdom for a proper binary search approach to finding
432 // cursors!
433 std::pair<FileID, unsigned> Location
434 = AU->getSourceManager().getDecomposedInstantiationLoc(
435 RegionOfInterest.getBegin());
436 if (Location.first != AU->getSourceManager().getMainFileID())
437 OnlyLocalDecls = false;
438 }
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000439
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000440 PreprocessingRecord::iterator StartEntity, EndEntity;
441 if (OnlyLocalDecls) {
442 StartEntity = AU->pp_entity_begin();
443 EndEntity = AU->pp_entity_end();
444 } else {
445 StartEntity = PPRec.begin();
446 EndEntity = PPRec.end();
447 }
448
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000449 // There is no region of interest; we have to walk everything.
450 if (RegionOfInterest.isInvalid())
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000451 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000452
453 // Find the file in which the region of interest lands.
Ted Kremenek91554282010-11-16 08:15:36 +0000454 SourceManager &SM = AU->getSourceManager();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000455 std::pair<FileID, unsigned> Begin
456 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
457 std::pair<FileID, unsigned> End
458 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
459
460 // The region of interest spans files; we have to walk everything.
461 if (Begin.first != End.first)
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000462 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000463
464 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
Ted Kremenek91554282010-11-16 08:15:36 +0000465 = AU->getPreprocessedEntitiesByFile();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000466 if (ByFileMap.empty()) {
467 // Build the mapping from files to sets of preprocessed entities.
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000468 for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000469 std::pair<FileID, unsigned> P
470 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000471
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000472 ByFileMap[P.first].push_back(*E);
473 }
474 }
475
476 return std::make_pair(ByFileMap[Begin.first].begin(),
477 ByFileMap[Begin.first].end());
478}
479
Douglas Gregor71f3d942010-01-20 20:59:29 +0000480/// \brief Visit the children of the given cursor.
Ted Kremenek91554282010-11-16 08:15:36 +0000481///
Douglas Gregor71f3d942010-01-20 20:59:29 +0000482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
Ted Kremenekf441baf2010-02-17 00:41:40 +0000484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregor64f38ae2011-03-02 19:17:03 +0000485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000487 // By definition, references have no children.
488 return false;
489 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000490
491 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregor71f3d942010-01-20 20:59:29 +0000492 // done.
Ted Kremenek12e0f292010-05-13 00:25:00 +0000493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf441baf2010-02-17 00:41:40 +0000494
Douglas Gregor71f3d942010-01-20 20:59:29 +0000495 if (clang_isDeclaration(Cursor.kind)) {
496 Decl *D = getCursorDecl(Cursor);
497 assert(D && "Invalid declaration cursor");
Ted Kremenek0e293092010-02-18 18:47:01 +0000498 return VisitAttributes(D) || Visit(D);
Douglas Gregor71f3d942010-01-20 20:59:29 +0000499 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000500
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000501 if (clang_isStatement(Cursor.kind))
502 return Visit(getCursorStmt(Cursor));
503 if (clang_isExpression(Cursor.kind))
504 return Visit(getCursorExpr(Cursor));
Ted Kremenekf441baf2010-02-17 00:41:40 +0000505
Douglas Gregor71f3d942010-01-20 20:59:29 +0000506 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremenek91554282010-11-16 08:15:36 +0000507 CXTranslationUnit tu = getCursorTU(Cursor);
508 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregorc2b97992011-03-16 23:23:30 +0000509
510 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
511 for (unsigned I = 0; I != 2; ++I) {
512 if (VisitOrder[I]) {
513 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
514 RegionOfInterest.isInvalid()) {
515 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
516 TLEnd = CXXUnit->top_level_end();
517 TL != TLEnd; ++TL) {
518 if (Visit(MakeCXCursor(*TL, tu), true))
519 return true;
520 }
521 } else if (VisitDeclContext(
522 CXXUnit->getASTContext().getTranslationUnitDecl()))
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000523 return true;
Douglas Gregorc2b97992011-03-16 23:23:30 +0000524 continue;
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000525 }
Bob Wilson4f559a32010-03-19 03:57:57 +0000526
Douglas Gregorc2b97992011-03-16 23:23:30 +0000527 // Walk the preprocessing record.
528 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
529 // FIXME: Once we have the ability to deserialize a preprocessing record,
530 // do so.
531 PreprocessingRecord::iterator E, EEnd;
532 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
533 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
534 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
535 return true;
536
537 continue;
538 }
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000539
Douglas Gregorc2b97992011-03-16 23:23:30 +0000540 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
541 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
542 return true;
543
544 continue;
545 }
Douglas Gregor5272e802010-03-19 05:22:59 +0000546
Douglas Gregorc2b97992011-03-16 23:23:30 +0000547 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
548 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
549 return true;
550
551 continue;
552 }
Douglas Gregor796d76a2010-10-20 22:00:55 +0000553 }
Douglas Gregor5272e802010-03-19 05:22:59 +0000554 }
555 }
Douglas Gregorc2b97992011-03-16 23:23:30 +0000556
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000557 return false;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000558 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000559
Douglas Gregor64f38ae2011-03-02 19:17:03 +0000560 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
561 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
562 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
563 return Visit(BaseTSInfo->getTypeLoc());
564 }
565 }
566 }
567
Douglas Gregor71f3d942010-01-20 20:59:29 +0000568 // Nothing to visit at the moment.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000569 return false;
570}
571
Ted Kremenek33b9a422010-04-11 21:47:37 +0000572bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
John McCalla3cecb62010-06-04 22:33:30 +0000573 if (Visit(B->getSignatureAsWritten()->getTypeLoc()))
574 return true;
Ted Kremenek33b9a422010-04-11 21:47:37 +0000575
Ted Kremenek60fe71a2010-07-22 11:30:19 +0000576 if (Stmt *Body = B->getBody())
577 return Visit(MakeCXCursor(Body, StmtParent, TU));
578
579 return false;
Ted Kremenek33b9a422010-04-11 21:47:37 +0000580}
581
Ted Kremenekd40a4392010-11-02 23:10:24 +0000582llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
583 if (RegionOfInterest.isValid()) {
Douglas Gregor29ee4222010-11-17 17:14:07 +0000584 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd40a4392010-11-02 23:10:24 +0000585 if (Range.isInvalid())
586 return llvm::Optional<bool>();
Douglas Gregor29ee4222010-11-17 17:14:07 +0000587
Ted Kremenekd40a4392010-11-02 23:10:24 +0000588 switch (CompareRegionOfInterest(Range)) {
589 case RangeBefore:
590 // This declaration comes before the region of interest; skip it.
591 return llvm::Optional<bool>();
592
593 case RangeAfter:
594 // This declaration comes after the region of interest; we're done.
595 return false;
596
597 case RangeOverlap:
598 // This declaration overlaps the region of interest; visit it.
599 break;
600 }
601 }
602 return true;
603}
604
605bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
606 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
607
608 // FIXME: Eventually remove. This part of a hack to support proper
609 // iteration over all Decls contained lexically within an ObjC container.
610 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
611 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
612
613 for ( ; I != E; ++I) {
Ted Kremenek49be9e02010-05-18 21:09:07 +0000614 Decl *D = *I;
615 if (D->getLexicalDeclContext() != DC)
616 continue;
Ted Kremenek49be9e02010-05-18 21:09:07 +0000617 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd40a4392010-11-02 23:10:24 +0000618 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
619 if (!V.hasValue())
620 continue;
621 if (!V.getValue())
622 return false;
Daniel Dunbar02968e52010-02-14 10:02:57 +0000623 if (Visit(Cursor, true))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000624 return true;
625 }
Douglas Gregor71f3d942010-01-20 20:59:29 +0000626 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +0000627}
628
Douglas Gregord824f882010-01-22 00:50:27 +0000629bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
630 llvm_unreachable("Translation units are visited directly by Visit()");
631 return false;
632}
633
634bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
635 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
636 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf441baf2010-02-17 00:41:40 +0000637
Douglas Gregord824f882010-01-22 00:50:27 +0000638 return false;
639}
640
641bool CursorVisitor::VisitTagDecl(TagDecl *D) {
642 return VisitDeclContext(D);
643}
644
Douglas Gregor9dc243c2010-09-01 17:32:36 +0000645bool CursorVisitor::VisitClassTemplateSpecializationDecl(
646 ClassTemplateSpecializationDecl *D) {
647 bool ShouldVisitBody = false;
648 switch (D->getSpecializationKind()) {
649 case TSK_Undeclared:
650 case TSK_ImplicitInstantiation:
651 // Nothing to visit
652 return false;
653
654 case TSK_ExplicitInstantiationDeclaration:
655 case TSK_ExplicitInstantiationDefinition:
656 break;
657
658 case TSK_ExplicitSpecialization:
659 ShouldVisitBody = true;
660 break;
661 }
662
663 // Visit the template arguments used in the specialization.
664 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
665 TypeLoc TL = SpecType->getTypeLoc();
666 if (TemplateSpecializationTypeLoc *TSTLoc
667 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
668 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
669 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
670 return true;
671 }
672 }
673
674 if (ShouldVisitBody && VisitCXXRecordDecl(D))
675 return true;
676
677 return false;
678}
679
Douglas Gregorf96abb22010-08-31 19:31:58 +0000680bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
681 ClassTemplatePartialSpecializationDecl *D) {
682 // FIXME: Visit the "outer" template parameter lists on the TagDecl
683 // before visiting these template parameters.
684 if (VisitTemplateParameters(D->getTemplateParameters()))
685 return true;
686
687 // Visit the partial specialization arguments.
688 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
689 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
690 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
691 return true;
692
693 return VisitCXXRecordDecl(D);
694}
695
Douglas Gregor713602b2010-08-31 17:01:39 +0000696bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000697 // Visit the default argument.
698 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
699 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
700 if (Visit(DefArg->getTypeLoc()))
701 return true;
702
Douglas Gregor713602b2010-08-31 17:01:39 +0000703 return false;
704}
705
Douglas Gregord824f882010-01-22 00:50:27 +0000706bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
707 if (Expr *Init = D->getInitExpr())
708 return Visit(MakeCXCursor(Init, StmtParent, TU));
709 return false;
710}
711
Douglas Gregor93f89952010-01-21 16:28:34 +0000712bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
713 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
714 if (Visit(TSInfo->getTypeLoc()))
715 return true;
716
Douglas Gregor14454802011-02-25 02:25:35 +0000717 // Visit the nested-name-specifier, if present.
718 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
719 if (VisitNestedNameSpecifierLoc(QualifierLoc))
720 return true;
721
Douglas Gregor93f89952010-01-21 16:28:34 +0000722 return false;
723}
724
Douglas Gregorf3af3112010-09-09 21:42:20 +0000725/// \brief Compare two base or member initializers based on their source order.
Alexis Hunt1d792652011-01-08 20:30:50 +0000726static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
727 CXXCtorInitializer const * const *X
728 = static_cast<CXXCtorInitializer const * const *>(Xp);
729 CXXCtorInitializer const * const *Y
730 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregorf3af3112010-09-09 21:42:20 +0000731
732 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
733 return -1;
734 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
735 return 1;
736 else
737 return 0;
738}
739
Douglas Gregor71f3d942010-01-20 20:59:29 +0000740bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor12bca222010-08-31 14:41:23 +0000741 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
742 // Visit the function declaration's syntactic components in the order
743 // written. This requires a bit of work.
Abramo Bagnara6d810632010-12-14 22:11:44 +0000744 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor12bca222010-08-31 14:41:23 +0000745 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
746
747 // If we have a function declared directly (without the use of a typedef),
748 // visit just the return type. Otherwise, just visit the function's type
749 // now.
750 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
751 (!FTL && Visit(TL)))
752 return true;
753
Douglas Gregor3335f482010-09-02 17:35:32 +0000754 // Visit the nested-name-specifier, if present.
Douglas Gregor14454802011-02-25 02:25:35 +0000755 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
756 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +0000757 return true;
Douglas Gregor12bca222010-08-31 14:41:23 +0000758
759 // Visit the declaration name.
760 if (VisitDeclarationNameInfo(ND->getNameInfo()))
761 return true;
762
763 // FIXME: Visit explicitly-specified template arguments!
764
765 // Visit the function parameters, if we have a function type.
766 if (FTL && VisitFunctionTypeLoc(*FTL, true))
767 return true;
768
769 // FIXME: Attributes?
770 }
771
Douglas Gregorf3af3112010-09-09 21:42:20 +0000772 if (ND->isThisDeclarationADefinition()) {
773 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
774 // Find the initializers that were written in the source.
Alexis Hunt1d792652011-01-08 20:30:50 +0000775 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregorf3af3112010-09-09 21:42:20 +0000776 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
777 IEnd = Constructor->init_end();
778 I != IEnd; ++I) {
779 if (!(*I)->isWritten())
780 continue;
781
782 WrittenInits.push_back(*I);
783 }
784
785 // Sort the initializers in source order
786 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Alexis Hunt1d792652011-01-08 20:30:50 +0000787 &CompareCXXCtorInitializers);
Douglas Gregorf3af3112010-09-09 21:42:20 +0000788
789 // Visit the initializers in source order
790 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Alexis Hunt1d792652011-01-08 20:30:50 +0000791 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichetd583da02010-12-04 09:14:42 +0000792 if (Init->isAnyMemberInitializer()) {
793 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregorf3af3112010-09-09 21:42:20 +0000794 Init->getMemberLocation(), TU)))
795 return true;
796 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
797 if (Visit(BaseInfo->getTypeLoc()))
798 return true;
799 }
800
801 // Visit the initializer value.
802 if (Expr *Initializer = Init->getInit())
803 if (Visit(MakeCXCursor(Initializer, ND, TU)))
804 return true;
805 }
806 }
807
808 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
809 return true;
810 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000811
Douglas Gregor71f3d942010-01-20 20:59:29 +0000812 return false;
813}
Ted Kremenek78668fd2010-01-13 00:22:49 +0000814
Douglas Gregord824f882010-01-22 00:50:27 +0000815bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
816 if (VisitDeclaratorDecl(D))
817 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000818
Douglas Gregord824f882010-01-22 00:50:27 +0000819 if (Expr *BitWidth = D->getBitWidth())
820 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf441baf2010-02-17 00:41:40 +0000821
Douglas Gregord824f882010-01-22 00:50:27 +0000822 return false;
823}
824
825bool CursorVisitor::VisitVarDecl(VarDecl *D) {
826 if (VisitDeclaratorDecl(D))
827 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000828
Douglas Gregord824f882010-01-22 00:50:27 +0000829 if (Expr *Init = D->getInit())
830 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf441baf2010-02-17 00:41:40 +0000831
Douglas Gregord824f882010-01-22 00:50:27 +0000832 return false;
833}
834
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000835bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
836 if (VisitDeclaratorDecl(D))
837 return true;
838
839 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
840 if (Expr *DefArg = D->getDefaultArgument())
841 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
842
843 return false;
844}
845
Douglas Gregor713602b2010-08-31 17:01:39 +0000846bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
847 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
848 // before visiting these template parameters.
849 if (VisitTemplateParameters(D->getTemplateParameters()))
850 return true;
851
852 return VisitFunctionDecl(D->getTemplatedDecl());
853}
854
Douglas Gregor1fbaeb12010-08-31 19:02:00 +0000855bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
856 // FIXME: Visit the "outer" template parameter lists on the TagDecl
857 // before visiting these template parameters.
858 if (VisitTemplateParameters(D->getTemplateParameters()))
859 return true;
860
861 return VisitCXXRecordDecl(D->getTemplatedDecl());
862}
863
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000864bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
865 if (VisitTemplateParameters(D->getTemplateParameters()))
866 return true;
867
868 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
869 VisitTemplateArgumentLoc(D->getDefaultArgument()))
870 return true;
871
872 return false;
873}
874
Douglas Gregord824f882010-01-22 00:50:27 +0000875bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor12852d92010-03-08 14:59:44 +0000876 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
877 if (Visit(TSInfo->getTypeLoc()))
878 return true;
879
Ted Kremenekf441baf2010-02-17 00:41:40 +0000880 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregord824f882010-01-22 00:50:27 +0000881 PEnd = ND->param_end();
882 P != PEnd; ++P) {
883 if (Visit(MakeCXCursor(*P, TU)))
884 return true;
885 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000886
Douglas Gregord824f882010-01-22 00:50:27 +0000887 if (ND->isThisDeclarationADefinition() &&
888 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
889 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000890
Douglas Gregord824f882010-01-22 00:50:27 +0000891 return false;
892}
893
Ted Kremenekd40a4392010-11-02 23:10:24 +0000894namespace {
895 struct ContainerDeclsSort {
896 SourceManager &SM;
897 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
898 bool operator()(Decl *A, Decl *B) {
899 SourceLocation L_A = A->getLocStart();
900 SourceLocation L_B = B->getLocStart();
901 assert(L_A.isValid() && L_B.isValid());
902 return SM.isBeforeInTranslationUnit(L_A, L_B);
903 }
904 };
905}
906
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000907bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd40a4392010-11-02 23:10:24 +0000908 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
909 // an @implementation can lexically contain Decls that are not properly
910 // nested in the AST. When we identify such cases, we need to retrofit
911 // this nesting here.
912 if (!DI_current)
913 return VisitDeclContext(D);
914
915 // Scan the Decls that immediately come after the container
916 // in the current DeclContext. If any fall within the
917 // container's lexical region, stash them into a vector
918 // for later processing.
919 llvm::SmallVector<Decl *, 24> DeclsInContainer;
920 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremenek91554282010-11-16 08:15:36 +0000921 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd40a4392010-11-02 23:10:24 +0000922 if (EndLoc.isValid()) {
923 DeclContext::decl_iterator next = *DI_current;
924 while (++next != DE_current) {
925 Decl *D_next = *next;
926 if (!D_next)
927 break;
928 SourceLocation L = D_next->getLocStart();
929 if (!L.isValid())
930 break;
931 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
932 *DI_current = next;
933 DeclsInContainer.push_back(D_next);
934 continue;
935 }
936 break;
937 }
938 }
939
940 // The common case.
941 if (DeclsInContainer.empty())
942 return VisitDeclContext(D);
943
944 // Get all the Decls in the DeclContext, and sort them with the
945 // additional ones we've collected. Then visit them.
946 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
947 I!=E; ++I) {
948 Decl *subDecl = *I;
Ted Kremenek4bd4d752010-11-02 23:17:51 +0000949 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
950 subDecl->getLocStart().isInvalid())
Ted Kremenekd40a4392010-11-02 23:10:24 +0000951 continue;
952 DeclsInContainer.push_back(subDecl);
953 }
954
955 // Now sort the Decls so that they appear in lexical order.
956 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
957 ContainerDeclsSort(SM));
958
959 // Now visit the decls.
960 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
961 E = DeclsInContainer.end(); I != E; ++I) {
962 CXCursor Cursor = MakeCXCursor(*I, TU);
963 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
964 if (!V.hasValue())
965 continue;
966 if (!V.getValue())
967 return false;
968 if (Visit(Cursor, true))
969 return true;
970 }
971 return false;
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000972}
973
Douglas Gregor71f3d942010-01-20 20:59:29 +0000974bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorfed36b12010-01-20 23:57:43 +0000975 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
976 TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000977 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000978
Douglas Gregoref6eb842010-01-16 15:44:18 +0000979 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
980 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
981 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +0000982 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000983 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000984
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000985 return VisitObjCContainerDecl(ND);
Ted Kremenek78668fd2010-01-13 00:22:49 +0000986}
987
Douglas Gregord824f882010-01-22 00:50:27 +0000988bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
989 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
990 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
991 E = PID->protocol_end(); I != E; ++I, ++PL)
992 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
993 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000994
Douglas Gregord824f882010-01-22 00:50:27 +0000995 return VisitObjCContainerDecl(PID);
996}
997
Ted Kremenek49be9e02010-05-18 21:09:07 +0000998bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor9f0e1aa2010-09-09 17:09:21 +0000999 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCalla3cecb62010-06-04 22:33:30 +00001000 return true;
1001
Ted Kremenek49be9e02010-05-18 21:09:07 +00001002 // FIXME: This implements a workaround with @property declarations also being
1003 // installed in the DeclContext for the @interface. Eventually this code
1004 // should be removed.
1005 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1006 if (!CDecl || !CDecl->IsClassExtension())
1007 return false;
1008
1009 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1010 if (!ID)
1011 return false;
1012
1013 IdentifierInfo *PropertyId = PD->getIdentifier();
1014 ObjCPropertyDecl *prevDecl =
1015 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1016
1017 if (!prevDecl)
1018 return false;
1019
1020 // Visit synthesized methods since they will be skipped when visiting
1021 // the @interface.
1022 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremenek2f075632010-09-21 20:52:59 +00001023 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek49be9e02010-05-18 21:09:07 +00001024 if (Visit(MakeCXCursor(MD, TU)))
1025 return true;
1026
1027 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremenek2f075632010-09-21 20:52:59 +00001028 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek49be9e02010-05-18 21:09:07 +00001029 if (Visit(MakeCXCursor(MD, TU)))
1030 return true;
1031
1032 return false;
1033}
1034
Douglas Gregor71f3d942010-01-20 20:59:29 +00001035bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenek78668fd2010-01-13 00:22:49 +00001036 // Issue callbacks for super class.
Douglas Gregor71f3d942010-01-20 20:59:29 +00001037 if (D->getSuperClass() &&
1038 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf441baf2010-02-17 00:41:40 +00001039 D->getSuperClassLoc(),
Douglas Gregorfed36b12010-01-20 23:57:43 +00001040 TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001041 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001042
Douglas Gregoref6eb842010-01-16 15:44:18 +00001043 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1044 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1045 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +00001046 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001047 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001048
Douglas Gregor5e8cf372010-01-21 23:27:09 +00001049 return VisitObjCContainerDecl(D);
Ted Kremenek78668fd2010-01-13 00:22:49 +00001050}
1051
Douglas Gregord824f882010-01-22 00:50:27 +00001052bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1053 return VisitObjCContainerDecl(D);
Ted Kremenek78668fd2010-01-13 00:22:49 +00001054}
1055
Douglas Gregord824f882010-01-22 00:50:27 +00001056bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremeneke184ac52010-03-19 20:39:03 +00001057 // 'ID' could be null when dealing with invalid code.
1058 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1059 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1060 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001061
Douglas Gregord824f882010-01-22 00:50:27 +00001062 return VisitObjCImplDecl(D);
1063}
1064
1065bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1066#if 0
1067 // Issue callbacks for super class.
1068 // FIXME: No source location information!
1069 if (D->getSuperClass() &&
1070 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf441baf2010-02-17 00:41:40 +00001071 D->getSuperClassLoc(),
Douglas Gregord824f882010-01-22 00:50:27 +00001072 TU)))
1073 return true;
1074#endif
Ted Kremenekf441baf2010-02-17 00:41:40 +00001075
Douglas Gregord824f882010-01-22 00:50:27 +00001076 return VisitObjCImplDecl(D);
1077}
1078
1079bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1080 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1081 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1082 E = D->protocol_end();
1083 I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +00001084 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001085 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001086
1087 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +00001088}
1089
Douglas Gregord824f882010-01-22 00:50:27 +00001090bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1091 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1092 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1093 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001094
Douglas Gregord824f882010-01-22 00:50:27 +00001095 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +00001096}
1097
Douglas Gregorb1b71e52010-11-17 01:03:52 +00001098bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1099 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1100 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1101
1102 return false;
1103}
1104
Ted Kremenekbd67fb22010-05-06 23:38:21 +00001105bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1106 return VisitDeclContext(D);
1107}
1108
Douglas Gregora89314e2010-08-31 23:48:11 +00001109bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001110 // Visit nested-name-specifier.
Douglas Gregorc05ba2e2011-02-25 17:08:07 +00001111 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1112 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001113 return true;
Douglas Gregora89314e2010-08-31 23:48:11 +00001114
1115 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1116 D->getTargetNameLoc(), TU));
1117}
1118
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001119bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001120 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001121 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1122 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001123 return true;
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001124 }
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001125
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001126 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1127 return true;
1128
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001129 return VisitDeclarationNameInfo(D->getNameInfo());
1130}
1131
Douglas Gregor01a430132010-09-01 03:07:18 +00001132bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001133 // Visit nested-name-specifier.
Douglas Gregor12441b32011-02-25 16:33:46 +00001134 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1135 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001136 return true;
Douglas Gregor01a430132010-09-01 03:07:18 +00001137
1138 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1139 D->getIdentLocation(), TU));
1140}
1141
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001142bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001143 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001144 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1145 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001146 return true;
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001147 }
Douglas Gregor3335f482010-09-02 17:35:32 +00001148
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001149 return VisitDeclarationNameInfo(D->getNameInfo());
1150}
1151
1152bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1153 UnresolvedUsingTypenameDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001154 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001155 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1156 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001157 return true;
1158
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001159 return false;
1160}
1161
Douglas Gregor12bca222010-08-31 14:41:23 +00001162bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1163 switch (Name.getName().getNameKind()) {
1164 case clang::DeclarationName::Identifier:
1165 case clang::DeclarationName::CXXLiteralOperatorName:
1166 case clang::DeclarationName::CXXOperatorName:
1167 case clang::DeclarationName::CXXUsingDirective:
1168 return false;
1169
1170 case clang::DeclarationName::CXXConstructorName:
1171 case clang::DeclarationName::CXXDestructorName:
1172 case clang::DeclarationName::CXXConversionFunctionName:
1173 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1174 return Visit(TSInfo->getTypeLoc());
1175 return false;
1176
1177 case clang::DeclarationName::ObjCZeroArgSelector:
1178 case clang::DeclarationName::ObjCOneArgSelector:
1179 case clang::DeclarationName::ObjCMultiArgSelector:
1180 // FIXME: Per-identifier location info?
1181 return false;
1182 }
1183
1184 return false;
1185}
1186
Douglas Gregor3335f482010-09-02 17:35:32 +00001187bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1188 SourceRange Range) {
1189 // FIXME: This whole routine is a hack to work around the lack of proper
1190 // source information in nested-name-specifiers (PR5791). Since we do have
1191 // a beginning source location, we can visit the first component of the
1192 // nested-name-specifier, if it's a single-token component.
1193 if (!NNS)
1194 return false;
1195
1196 // Get the first component in the nested-name-specifier.
1197 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1198 NNS = Prefix;
1199
1200 switch (NNS->getKind()) {
1201 case NestedNameSpecifier::Namespace:
Douglas Gregor3335f482010-09-02 17:35:32 +00001202 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1203 TU));
1204
Douglas Gregor7b26ff92011-02-24 02:36:08 +00001205 case NestedNameSpecifier::NamespaceAlias:
1206 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1207 Range.getBegin(), TU));
1208
Douglas Gregor3335f482010-09-02 17:35:32 +00001209 case NestedNameSpecifier::TypeSpec: {
1210 // If the type has a form where we know that the beginning of the source
1211 // range matches up with a reference cursor. Visit the appropriate reference
1212 // cursor.
John McCall424cec92011-01-19 06:33:43 +00001213 const Type *T = NNS->getAsType();
Douglas Gregor3335f482010-09-02 17:35:32 +00001214 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1215 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1216 if (const TagType *Tag = dyn_cast<TagType>(T))
1217 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1218 if (const TemplateSpecializationType *TST
1219 = dyn_cast<TemplateSpecializationType>(T))
1220 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1221 break;
1222 }
1223
1224 case NestedNameSpecifier::TypeSpecWithTemplate:
1225 case NestedNameSpecifier::Global:
1226 case NestedNameSpecifier::Identifier:
1227 break;
1228 }
1229
1230 return false;
1231}
1232
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001233bool
1234CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1235 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1236 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1237 Qualifiers.push_back(Qualifier);
1238
1239 while (!Qualifiers.empty()) {
1240 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1241 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1242 switch (NNS->getKind()) {
1243 case NestedNameSpecifier::Namespace:
1244 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregor14454802011-02-25 02:25:35 +00001245 Q.getLocalBeginLoc(),
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001246 TU)))
1247 return true;
1248
1249 break;
1250
1251 case NestedNameSpecifier::NamespaceAlias:
1252 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Douglas Gregor14454802011-02-25 02:25:35 +00001253 Q.getLocalBeginLoc(),
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001254 TU)))
1255 return true;
1256
1257 break;
1258
1259 case NestedNameSpecifier::TypeSpec:
1260 case NestedNameSpecifier::TypeSpecWithTemplate:
1261 if (Visit(Q.getTypeLoc()))
1262 return true;
1263
1264 break;
1265
1266 case NestedNameSpecifier::Global:
1267 case NestedNameSpecifier::Identifier:
1268 break;
1269 }
1270 }
1271
1272 return false;
1273}
1274
Douglas Gregor713602b2010-08-31 17:01:39 +00001275bool CursorVisitor::VisitTemplateParameters(
1276 const TemplateParameterList *Params) {
1277 if (!Params)
1278 return false;
1279
1280 for (TemplateParameterList::const_iterator P = Params->begin(),
1281 PEnd = Params->end();
1282 P != PEnd; ++P) {
1283 if (Visit(MakeCXCursor(*P, TU)))
1284 return true;
1285 }
1286
1287 return false;
1288}
1289
Douglas Gregora23e8f72010-08-31 20:37:03 +00001290bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1291 switch (Name.getKind()) {
1292 case TemplateName::Template:
1293 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1294
1295 case TemplateName::OverloadedTemplate:
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001296 // Visit the overloaded template set.
1297 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1298 return true;
1299
Douglas Gregora23e8f72010-08-31 20:37:03 +00001300 return false;
1301
1302 case TemplateName::DependentTemplate:
1303 // FIXME: Visit nested-name-specifier.
1304 return false;
1305
1306 case TemplateName::QualifiedTemplate:
1307 // FIXME: Visit nested-name-specifier.
1308 return Visit(MakeCursorTemplateRef(
1309 Name.getAsQualifiedTemplateName()->getDecl(),
1310 Loc, TU));
Douglas Gregor5590be02011-01-15 06:45:20 +00001311
1312 case TemplateName::SubstTemplateTemplateParmPack:
1313 return Visit(MakeCursorTemplateRef(
1314 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1315 Loc, TU));
Douglas Gregora23e8f72010-08-31 20:37:03 +00001316 }
1317
1318 return false;
1319}
1320
Douglas Gregor713602b2010-08-31 17:01:39 +00001321bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1322 switch (TAL.getArgument().getKind()) {
1323 case TemplateArgument::Null:
1324 case TemplateArgument::Integral:
Douglas Gregor0192c232010-12-20 16:52:59 +00001325 case TemplateArgument::Pack:
Douglas Gregor713602b2010-08-31 17:01:39 +00001326 return false;
1327
Douglas Gregor713602b2010-08-31 17:01:39 +00001328 case TemplateArgument::Type:
1329 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1330 return Visit(TSInfo->getTypeLoc());
1331 return false;
1332
1333 case TemplateArgument::Declaration:
1334 if (Expr *E = TAL.getSourceDeclExpression())
1335 return Visit(MakeCXCursor(E, StmtParent, TU));
1336 return false;
1337
1338 case TemplateArgument::Expression:
1339 if (Expr *E = TAL.getSourceExpression())
1340 return Visit(MakeCXCursor(E, StmtParent, TU));
1341 return false;
1342
1343 case TemplateArgument::Template:
Douglas Gregore4ff4b52011-01-05 18:58:31 +00001344 case TemplateArgument::TemplateExpansion:
Douglas Gregor9d802122011-03-02 17:09:35 +00001345 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1346 return true;
1347
Douglas Gregore4ff4b52011-01-05 18:58:31 +00001348 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregora23e8f72010-08-31 20:37:03 +00001349 TAL.getTemplateNameLoc());
Douglas Gregor713602b2010-08-31 17:01:39 +00001350 }
1351
1352 return false;
1353}
1354
Ted Kremenekb80cba52010-05-07 01:04:29 +00001355bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1356 return VisitDeclContext(D);
1357}
1358
Douglas Gregor12bca222010-08-31 14:41:23 +00001359bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1360 return Visit(TL.getUnqualifiedLoc());
1361}
1362
Douglas Gregord1824312010-01-21 17:29:07 +00001363bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremenek91554282010-11-16 08:15:36 +00001364 ASTContext &Context = AU->getASTContext();
Douglas Gregord1824312010-01-21 17:29:07 +00001365
1366 // Some builtin types (such as Objective-C's "id", "sel", and
1367 // "Class") have associated declarations. Create cursors for those.
1368 QualType VisitType;
1369 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001370 case BuiltinType::Void:
Douglas Gregord1824312010-01-21 17:29:07 +00001371 case BuiltinType::Bool:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001372 case BuiltinType::Char_U:
1373 case BuiltinType::UChar:
Douglas Gregord1824312010-01-21 17:29:07 +00001374 case BuiltinType::Char16:
1375 case BuiltinType::Char32:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001376 case BuiltinType::UShort:
Douglas Gregord1824312010-01-21 17:29:07 +00001377 case BuiltinType::UInt:
1378 case BuiltinType::ULong:
1379 case BuiltinType::ULongLong:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001380 case BuiltinType::UInt128:
1381 case BuiltinType::Char_S:
1382 case BuiltinType::SChar:
Chris Lattnerad3467e2010-12-25 23:25:43 +00001383 case BuiltinType::WChar_U:
1384 case BuiltinType::WChar_S:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001385 case BuiltinType::Short:
1386 case BuiltinType::Int:
1387 case BuiltinType::Long:
1388 case BuiltinType::LongLong:
1389 case BuiltinType::Int128:
1390 case BuiltinType::Float:
1391 case BuiltinType::Double:
1392 case BuiltinType::LongDouble:
1393 case BuiltinType::NullPtr:
1394 case BuiltinType::Overload:
1395 case BuiltinType::Dependent:
Douglas Gregord1824312010-01-21 17:29:07 +00001396 break;
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001397
Ted Kremenekfcb3db72010-02-18 18:52:18 +00001398 case BuiltinType::ObjCId:
1399 VisitType = Context.getObjCIdType();
1400 break;
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001401
1402 case BuiltinType::ObjCClass:
1403 VisitType = Context.getObjCClassType();
1404 break;
1405
Douglas Gregord1824312010-01-21 17:29:07 +00001406 case BuiltinType::ObjCSel:
1407 VisitType = Context.getObjCSelType();
1408 break;
1409 }
1410
1411 if (!VisitType.isNull()) {
1412 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf441baf2010-02-17 00:41:40 +00001413 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregord1824312010-01-21 17:29:07 +00001414 TU));
1415 }
1416
1417 return false;
1418}
1419
Douglas Gregor93f89952010-01-21 16:28:34 +00001420bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1421 return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
1422}
1423
Douglas Gregord1824312010-01-21 17:29:07 +00001424bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1425 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1426}
1427
1428bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1429 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1430}
1431
Douglas Gregor713602b2010-08-31 17:01:39 +00001432bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001433 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregor713602b2010-08-31 17:01:39 +00001434 // no context information with which we can match up the depth/index in the
1435 // type to the appropriate
1436 return false;
1437}
1438
Douglas Gregord1824312010-01-21 17:29:07 +00001439bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1440 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1441 return true;
1442
John McCall8b07ec22010-05-15 11:32:37 +00001443 return false;
1444}
1445
1446bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1447 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1448 return true;
1449
Douglas Gregord1824312010-01-21 17:29:07 +00001450 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1451 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1452 TU)))
1453 return true;
1454 }
1455
1456 return false;
1457}
1458
1459bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCall8b07ec22010-05-15 11:32:37 +00001460 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001461}
1462
Abramo Bagnara924a8f32010-12-10 16:29:40 +00001463bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1464 return Visit(TL.getInnerLoc());
1465}
1466
Douglas Gregord1824312010-01-21 17:29:07 +00001467bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1468 return Visit(TL.getPointeeLoc());
1469}
1470
1471bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1472 return Visit(TL.getPointeeLoc());
1473}
1474
1475bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1476 return Visit(TL.getPointeeLoc());
1477}
1478
1479bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00001480 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001481}
1482
1483bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00001484 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001485}
1486
Douglas Gregor12bca222010-08-31 14:41:23 +00001487bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1488 bool SkipResultType) {
1489 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregord1824312010-01-21 17:29:07 +00001490 return true;
1491
Douglas Gregord1824312010-01-21 17:29:07 +00001492 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek6ca136a2010-04-07 00:27:13 +00001493 if (Decl *D = TL.getArg(I))
1494 if (Visit(MakeCXCursor(D, TU)))
1495 return true;
Douglas Gregord1824312010-01-21 17:29:07 +00001496
1497 return false;
1498}
1499
1500bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1501 if (Visit(TL.getElementLoc()))
1502 return true;
1503
1504 if (Expr *Size = TL.getSizeExpr())
1505 return Visit(MakeCXCursor(Size, StmtParent, TU));
1506
1507 return false;
1508}
1509
Douglas Gregor713602b2010-08-31 17:01:39 +00001510bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1511 TemplateSpecializationTypeLoc TL) {
Douglas Gregora23e8f72010-08-31 20:37:03 +00001512 // Visit the template name.
1513 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1514 TL.getTemplateNameLoc()))
1515 return true;
Douglas Gregor713602b2010-08-31 17:01:39 +00001516
1517 // Visit the template arguments.
1518 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1519 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1520 return true;
1521
1522 return false;
1523}
1524
Douglas Gregor6479fc42010-01-21 20:48:56 +00001525bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1526 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1527}
1528
1529bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1530 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1531 return Visit(TSInfo->getTypeLoc());
1532
1533 return false;
1534}
1535
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00001536bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1537 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1538 return true;
1539
1540 return false;
1541}
1542
Douglas Gregora7a795b2011-03-01 20:11:18 +00001543bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1544 DependentTemplateSpecializationTypeLoc TL) {
1545 // Visit the nested-name-specifier, if there is one.
1546 if (TL.getQualifierLoc() &&
1547 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1548 return true;
1549
1550 // Visit the template arguments.
1551 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1552 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1553 return true;
1554
1555 return false;
1556}
1557
Douglas Gregor844cb502011-03-01 18:12:44 +00001558bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1559 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1560 return true;
1561
1562 return Visit(TL.getNamedTypeLoc());
1563}
1564
Douglas Gregord2fa7662010-12-20 02:24:11 +00001565bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1566 return Visit(TL.getPatternLoc());
1567}
1568
Ted Kremenekae9e2212010-08-27 21:34:58 +00001569bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregor14454802011-02-25 02:25:35 +00001570 // Visit the nested-name-specifier, if present.
1571 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1572 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1573 return true;
1574
Ted Kremenekae9e2212010-08-27 21:34:58 +00001575 if (D->isDefinition()) {
1576 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1577 E = D->bases_end(); I != E; ++I) {
1578 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1579 return true;
1580 }
1581 }
1582
1583 return VisitTagDecl(D);
1584}
1585
Ted Kremenek6ab9aa022010-02-18 05:46:33 +00001586bool CursorVisitor::VisitAttributes(Decl *D) {
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001587 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1588 i != e; ++i)
1589 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek6ab9aa022010-02-18 05:46:33 +00001590 return true;
1591
1592 return false;
1593}
1594
Ted Kremenek92209a42010-11-11 08:05:18 +00001595//===----------------------------------------------------------------------===//
1596// Data-recursive visitor methods.
1597//===----------------------------------------------------------------------===//
1598
Ted Kremenekacff73c2010-11-13 00:36:47 +00001599namespace {
Ted Kremenek072e6372010-11-13 00:36:50 +00001600#define DEF_JOB(NAME, DATA, KIND)\
1601class NAME : public VisitorJob {\
1602public:\
1603 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1604 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenek83900272010-11-18 00:02:32 +00001605 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek072e6372010-11-13 00:36:50 +00001606};
1607
1608DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1609DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremenek573411b2010-11-13 00:58:18 +00001610DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek072e6372010-11-13 00:36:50 +00001611DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001612DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1613 ExplicitTemplateArgsVisitKind)
Douglas Gregor557f05c2011-01-19 20:34:17 +00001614DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek072e6372010-11-13 00:36:50 +00001615#undef DEF_JOB
1616
1617class DeclVisit : public VisitorJob {
1618public:
1619 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1620 VisitorJob(parent, VisitorJob::DeclVisitKind,
1621 d, isFirst ? (void*) 1 : (void*) 0) {}
1622 static bool classof(const VisitorJob *VJ) {
Ted Kremeneke6f03042010-11-15 22:23:26 +00001623 return VJ->getKind() == DeclVisitKind;
Ted Kremenek072e6372010-11-13 00:36:50 +00001624 }
Ted Kremenek83900272010-11-18 00:02:32 +00001625 Decl *get() const { return static_cast<Decl*>(data[0]); }
1626 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek072e6372010-11-13 00:36:50 +00001627};
Ted Kremenek072e6372010-11-13 00:36:50 +00001628class TypeLocVisit : public VisitorJob {
1629public:
1630 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1631 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1632 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1633
1634 static bool classof(const VisitorJob *VJ) {
1635 return VJ->getKind() == TypeLocVisitKind;
1636 }
1637
Ted Kremeneke6f03042010-11-15 22:23:26 +00001638 TypeLoc get() const {
Ted Kremenek83900272010-11-18 00:02:32 +00001639 QualType T = QualType::getFromOpaquePtr(data[0]);
1640 return TypeLoc(T, data[1]);
Ted Kremenek072e6372010-11-13 00:36:50 +00001641 }
1642};
1643
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001644class LabelRefVisit : public VisitorJob {
1645public:
Chris Lattnerc8e630e2011-02-17 07:39:24 +00001646 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1647 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001648 labelLoc.getPtrEncoding()) {}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001649
1650 static bool classof(const VisitorJob *VJ) {
1651 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1652 }
Chris Lattnerc8e630e2011-02-17 07:39:24 +00001653 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001654 SourceLocation getLoc() const {
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001655 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenek83900272010-11-18 00:02:32 +00001656};
1657class NestedNameSpecifierVisit : public VisitorJob {
1658public:
1659 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1660 CXCursor parent)
1661 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001662 NS, R.getBegin().getPtrEncoding(),
1663 R.getEnd().getPtrEncoding()) {}
Ted Kremenek83900272010-11-18 00:02:32 +00001664 static bool classof(const VisitorJob *VJ) {
1665 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1666 }
1667 NestedNameSpecifier *get() const {
1668 return static_cast<NestedNameSpecifier*>(data[0]);
1669 }
1670 SourceRange getSourceRange() const {
1671 SourceLocation A =
1672 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1673 SourceLocation B =
1674 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1675 return SourceRange(A, B);
1676 }
1677};
Douglas Gregora6ce6082011-02-25 18:19:59 +00001678
1679class NestedNameSpecifierLocVisit : public VisitorJob {
1680public:
1681 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1682 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1683 Qualifier.getNestedNameSpecifier(),
1684 Qualifier.getOpaqueData()) { }
1685
1686 static bool classof(const VisitorJob *VJ) {
1687 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1688 }
1689
1690 NestedNameSpecifierLoc get() const {
1691 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1692 data[1]);
1693 }
1694};
1695
Ted Kremenek83900272010-11-18 00:02:32 +00001696class DeclarationNameInfoVisit : public VisitorJob {
1697public:
1698 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1699 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1700 static bool classof(const VisitorJob *VJ) {
1701 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1702 }
1703 DeclarationNameInfo get() const {
1704 Stmt *S = static_cast<Stmt*>(data[0]);
1705 switch (S->getStmtClass()) {
1706 default:
1707 llvm_unreachable("Unhandled Stmt");
1708 case Stmt::CXXDependentScopeMemberExprClass:
1709 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1710 case Stmt::DependentScopeDeclRefExprClass:
1711 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1712 }
1713 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001714};
Ted Kremenek5d304a32010-11-18 00:42:18 +00001715class MemberRefVisit : public VisitorJob {
1716public:
1717 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1718 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001719 L.getPtrEncoding()) {}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001720 static bool classof(const VisitorJob *VJ) {
1721 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1722 }
1723 FieldDecl *get() const {
1724 return static_cast<FieldDecl*>(data[0]);
1725 }
1726 SourceLocation getLoc() const {
1727 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1728 }
1729};
Ted Kremenekacff73c2010-11-13 00:36:47 +00001730class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1731 VisitorWorkList &WL;
1732 CXCursor Parent;
1733public:
1734 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1735 : WL(wl), Parent(parent) {}
1736
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001737 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001738 void VisitBlockExpr(BlockExpr *B);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001739 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenekfdc52372010-11-13 05:38:03 +00001740 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001741 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenek83900272010-11-18 00:02:32 +00001742 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001743 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek9f49b372010-11-17 02:18:35 +00001744 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001745 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001746 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001747 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremeneka51cc432010-11-17 00:50:41 +00001748 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek79ddc672010-11-17 00:50:36 +00001749 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek7003a502010-11-17 00:50:52 +00001750 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremenek573411b2010-11-13 00:58:18 +00001751 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek072e6372010-11-13 00:36:50 +00001752 void VisitDeclStmt(DeclStmt *S);
Ted Kremenek83900272010-11-18 00:02:32 +00001753 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001754 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001755 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1756 void VisitForStmt(ForStmt *FS);
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001757 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001758 void VisitIfStmt(IfStmt *If);
1759 void VisitInitListExpr(InitListExpr *IE);
1760 void VisitMemberExpr(MemberExpr *M);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001761 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001762 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001763 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1764 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournee190dee2011-03-11 19:24:49 +00001765 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001766 void VisitStmt(Stmt *S);
1767 void VisitSwitchStmt(SwitchStmt *S);
1768 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek513cd572010-11-17 00:50:50 +00001769 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00001770 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001771 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenekc1c30cd2010-11-17 00:50:43 +00001772 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor557f05c2011-01-19 20:34:17 +00001773 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregor820ba7b2011-01-04 17:33:58 +00001774
Ted Kremenekacff73c2010-11-13 00:36:47 +00001775private:
Ted Kremenek83900272010-11-18 00:02:32 +00001776 void AddDeclarationNameInfo(Stmt *S);
1777 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregora6ce6082011-02-25 18:19:59 +00001778 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001779 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001780 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001781 void AddStmt(Stmt *S);
Ted Kremenek072e6372010-11-13 00:36:50 +00001782 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001783 void AddTypeLoc(TypeSourceInfo *TI);
1784 void EnqueueChildren(Stmt *S);
1785};
1786} // end anonyous namespace
1787
Ted Kremenek83900272010-11-18 00:02:32 +00001788void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1789 // 'S' should always be non-null, since it comes from the
1790 // statement we are visiting.
1791 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1792}
1793void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1794 SourceRange R) {
1795 if (N)
1796 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1797}
Douglas Gregora6ce6082011-02-25 18:19:59 +00001798
1799void
1800EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1801 if (Qualifier)
1802 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1803}
1804
Ted Kremenekacff73c2010-11-13 00:36:47 +00001805void EnqueueVisitor::AddStmt(Stmt *S) {
1806 if (S)
1807 WL.push_back(StmtVisit(S, Parent));
1808}
Ted Kremenek072e6372010-11-13 00:36:50 +00001809void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00001810 if (D)
Ted Kremenek072e6372010-11-13 00:36:50 +00001811 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenekacff73c2010-11-13 00:36:47 +00001812}
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001813void EnqueueVisitor::
1814 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1815 if (A)
1816 WL.push_back(ExplicitTemplateArgsVisit(
1817 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1818}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001819void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1820 if (D)
1821 WL.push_back(MemberRefVisit(D, L, Parent));
1822}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001823void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1824 if (TI)
1825 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1826 }
1827void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremenek6a5df572010-11-12 21:34:09 +00001828 unsigned size = WL.size();
John McCall8322c3a2011-02-13 04:07:26 +00001829 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00001830 AddStmt(*Child);
Ted Kremenek6a5df572010-11-12 21:34:09 +00001831 }
1832 if (size == WL.size())
1833 return;
1834 // Now reverse the entries we just added. This will match the DFS
1835 // ordering performed by the worklist.
1836 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1837 std::reverse(I, E);
1838}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001839void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1840 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1841}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001842void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1843 AddDecl(B->getBlockDecl());
1844}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001845void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1846 EnqueueChildren(E);
1847 AddTypeLoc(E->getTypeSourceInfo());
1848}
Ted Kremenekfdc52372010-11-13 05:38:03 +00001849void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1850 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1851 E = S->body_rend(); I != E; ++I) {
1852 AddStmt(*I);
1853 }
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001854}
Ted Kremenek83900272010-11-18 00:02:32 +00001855void EnqueueVisitor::
1856VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1857 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1858 AddDeclarationNameInfo(E);
Douglas Gregore16af532011-02-28 18:50:33 +00001859 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1860 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenek83900272010-11-18 00:02:32 +00001861 if (!E->isImplicitAccess())
1862 AddStmt(E->getBase());
1863}
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001864void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1865 // Enqueue the initializer or constructor arguments.
1866 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1867 AddStmt(E->getConstructorArg(I-1));
1868 // Enqueue the array size, if any.
1869 AddStmt(E->getArraySize());
1870 // Enqueue the allocated type.
1871 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1872 // Enqueue the placement arguments.
1873 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1874 AddStmt(E->getPlacementArg(I-1));
1875}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001876void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenekbc8b3782010-11-13 05:55:56 +00001877 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1878 AddStmt(CE->getArg(I-1));
Ted Kremenekacff73c2010-11-13 00:36:47 +00001879 AddStmt(CE->getCallee());
1880 AddStmt(CE->getArg(0));
1881}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001882void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1883 // Visit the name of the type being destroyed.
1884 AddTypeLoc(E->getDestroyedTypeInfo());
1885 // Visit the scope type that looks disturbingly like the nested-name-specifier
1886 // but isn't.
1887 AddTypeLoc(E->getScopeTypeInfo());
1888 // Visit the nested-name-specifier.
Douglas Gregora6ce6082011-02-25 18:19:59 +00001889 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1890 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001891 // Visit base expression.
1892 AddStmt(E->getBase());
1893}
Ted Kremenek9f49b372010-11-17 02:18:35 +00001894void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1895 AddTypeLoc(E->getTypeSourceInfo());
1896}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001897void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1898 EnqueueChildren(E);
1899 AddTypeLoc(E->getTypeSourceInfo());
1900}
Ted Kremeneka51cc432010-11-17 00:50:41 +00001901void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1902 EnqueueChildren(E);
1903 if (E->isTypeOperand())
1904 AddTypeLoc(E->getTypeOperandSourceInfo());
1905}
Ted Kremenek79ddc672010-11-17 00:50:36 +00001906
1907void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1908 *E) {
1909 EnqueueChildren(E);
1910 AddTypeLoc(E->getTypeSourceInfo());
1911}
Ted Kremenek7003a502010-11-17 00:50:52 +00001912void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1913 EnqueueChildren(E);
1914 if (E->isTypeOperand())
1915 AddTypeLoc(E->getTypeOperandSourceInfo());
1916}
Ted Kremenek573411b2010-11-13 00:58:18 +00001917void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001918 if (DR->hasExplicitTemplateArgs()) {
1919 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1920 }
Ted Kremenek573411b2010-11-13 00:58:18 +00001921 WL.push_back(DeclRefExprParts(DR, Parent));
1922}
Ted Kremenek83900272010-11-18 00:02:32 +00001923void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1924 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1925 AddDeclarationNameInfo(E);
Douglas Gregor3a43fd62011-02-25 20:49:16 +00001926 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenek83900272010-11-18 00:02:32 +00001927}
Ted Kremenek072e6372010-11-13 00:36:50 +00001928void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1929 unsigned size = WL.size();
1930 bool isFirst = true;
1931 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1932 D != DEnd; ++D) {
1933 AddDecl(*D, isFirst);
1934 isFirst = false;
1935 }
1936 if (size == WL.size())
1937 return;
1938 // Now reverse the entries we just added. This will match the DFS
1939 // ordering performed by the worklist.
1940 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1941 std::reverse(I, E);
1942}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001943void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1944 AddStmt(E->getInit());
1945 typedef DesignatedInitExpr::Designator Designator;
1946 for (DesignatedInitExpr::reverse_designators_iterator
1947 D = E->designators_rbegin(), DEnd = E->designators_rend();
1948 D != DEnd; ++D) {
1949 if (D->isFieldDesignator()) {
1950 if (FieldDecl *Field = D->getField())
1951 AddMemberRef(Field, D->getFieldLoc());
1952 continue;
1953 }
1954 if (D->isArrayDesignator()) {
1955 AddStmt(E->getArrayIndex(*D));
1956 continue;
1957 }
1958 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1959 AddStmt(E->getArrayRangeEnd(*D));
1960 AddStmt(E->getArrayRangeStart(*D));
1961 }
1962}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001963void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1964 EnqueueChildren(E);
1965 AddTypeLoc(E->getTypeInfoAsWritten());
1966}
1967void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1968 AddStmt(FS->getBody());
1969 AddStmt(FS->getInc());
1970 AddStmt(FS->getCond());
1971 AddDecl(FS->getConditionVariable());
1972 AddStmt(FS->getInit());
1973}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001974void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1975 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1976}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001977void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
1978 AddStmt(If->getElse());
1979 AddStmt(If->getThen());
1980 AddStmt(If->getCond());
1981 AddDecl(If->getConditionVariable());
1982}
1983void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
1984 // We care about the syntactic form of the initializer list, only.
1985 if (InitListExpr *Syntactic = IE->getSyntacticForm())
1986 IE = Syntactic;
1987 EnqueueChildren(IE);
1988}
1989void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor30313cb2010-11-17 17:15:08 +00001990 WL.push_back(MemberExprParts(M, Parent));
1991
1992 // If the base of the member access expression is an implicit 'this', don't
1993 // visit it.
1994 // FIXME: If we ever want to show these implicit accesses, this will be
1995 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor25b7e052011-03-02 21:06:53 +00001996 if (!M->isImplicitAccess())
1997 AddStmt(M->getBase());
Ted Kremenekacff73c2010-11-13 00:36:47 +00001998}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001999void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2000 AddTypeLoc(E->getEncodedTypeSourceInfo());
2001}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002002void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2003 EnqueueChildren(M);
2004 AddTypeLoc(M->getClassReceiverTypeInfo());
2005}
Ted Kremenek5d304a32010-11-18 00:42:18 +00002006void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2007 // Visit the components of the offsetof expression.
2008 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2009 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2010 const OffsetOfNode &Node = E->getComponent(I-1);
2011 switch (Node.getKind()) {
2012 case OffsetOfNode::Array:
2013 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2014 break;
2015 case OffsetOfNode::Field:
Abramo Bagnara6b6f0512011-03-12 09:45:03 +00002016 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenek5d304a32010-11-18 00:42:18 +00002017 break;
2018 case OffsetOfNode::Identifier:
2019 case OffsetOfNode::Base:
2020 continue;
2021 }
2022 }
2023 // Visit the type into which we're computing the offset.
2024 AddTypeLoc(E->getTypeSourceInfo());
2025}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002026void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek8eaa1652010-11-17 00:50:47 +00002027 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002028 WL.push_back(OverloadExprParts(E, Parent));
2029}
Peter Collingbournee190dee2011-03-11 19:24:49 +00002030void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2031 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek9f49b372010-11-17 02:18:35 +00002032 EnqueueChildren(E);
2033 if (E->isArgumentType())
2034 AddTypeLoc(E->getArgumentTypeInfo());
2035}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002036void EnqueueVisitor::VisitStmt(Stmt *S) {
2037 EnqueueChildren(S);
2038}
2039void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2040 AddStmt(S->getBody());
2041 AddStmt(S->getCond());
2042 AddDecl(S->getConditionVariable());
2043}
Ted Kremenekdd0d4b42010-11-17 00:50:39 +00002044
Ted Kremenekacff73c2010-11-13 00:36:47 +00002045void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2046 AddStmt(W->getBody());
2047 AddStmt(W->getCond());
2048 AddDecl(W->getConditionVariable());
2049}
Ted Kremenek513cd572010-11-17 00:50:50 +00002050void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2051 AddTypeLoc(E->getQueriedTypeSourceInfo());
2052}
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002053
2054void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002055 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichetcf7731b2010-12-08 09:11:05 +00002056 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002057}
2058
Ted Kremenekacff73c2010-11-13 00:36:47 +00002059void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2060 VisitOverloadExpr(U);
2061 if (!U->isImplicitAccess())
2062 AddStmt(U->getBase());
2063}
Ted Kremenekc1c30cd2010-11-17 00:50:43 +00002064void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2065 AddStmt(E->getSubExpr());
2066 AddTypeLoc(E->getWrittenTypeInfo());
2067}
Douglas Gregor557f05c2011-01-19 20:34:17 +00002068void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2069 WL.push_back(SizeOfPackExprParts(E, Parent));
2070}
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002071
Ted Kremenek92209a42010-11-11 08:05:18 +00002072void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00002073 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenek92209a42010-11-11 08:05:18 +00002074}
2075
2076bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2077 if (RegionOfInterest.isValid()) {
2078 SourceRange Range = getRawCursorExtent(C);
2079 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2080 return false;
2081 }
2082 return true;
2083}
2084
2085bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2086 while (!WL.empty()) {
2087 // Dequeue the worklist item.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002088 VisitorJob LI = WL.back();
2089 WL.pop_back();
2090
Ted Kremenek92209a42010-11-11 08:05:18 +00002091 // Set the Parent field, then back to its old value once we're done.
2092 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2093
2094 switch (LI.getKind()) {
Ted Kremenek73227d72010-11-12 18:26:56 +00002095 case VisitorJob::DeclVisitKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002096 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenek73227d72010-11-12 18:26:56 +00002097 if (!D)
2098 continue;
2099
2100 // For now, perform default visitation for Decls.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002101 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenek73227d72010-11-12 18:26:56 +00002102 return true;
2103
2104 continue;
2105 }
Ted Kremenek8eaa1652010-11-17 00:50:47 +00002106 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2107 const ExplicitTemplateArgumentList *ArgList =
2108 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2109 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2110 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2111 Arg != ArgEnd; ++Arg) {
2112 if (VisitTemplateArgumentLoc(*Arg))
2113 return true;
2114 }
2115 continue;
2116 }
Ted Kremeneke12bcf52010-11-12 21:34:12 +00002117 case VisitorJob::TypeLocVisitKind: {
2118 // Perform default visitation for TypeLocs.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002119 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremeneke12bcf52010-11-12 21:34:12 +00002120 return true;
2121 continue;
2122 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00002123 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerc8e630e2011-02-17 07:39:24 +00002124 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremenekc49211c2011-02-23 04:54:51 +00002125 if (LabelStmt *stmt = LS->getStmt()) {
2126 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2127 TU))) {
2128 return true;
2129 }
2130 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00002131 continue;
2132 }
Douglas Gregora6ce6082011-02-25 18:19:59 +00002133
Ted Kremenek83900272010-11-18 00:02:32 +00002134 case VisitorJob::NestedNameSpecifierVisitKind: {
2135 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2136 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2137 return true;
2138 continue;
2139 }
Douglas Gregora6ce6082011-02-25 18:19:59 +00002140
2141 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2142 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2143 if (VisitNestedNameSpecifierLoc(V->get()))
2144 return true;
2145 continue;
2146 }
2147
Ted Kremenek83900272010-11-18 00:02:32 +00002148 case VisitorJob::DeclarationNameInfoVisitKind: {
2149 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2150 ->get()))
2151 return true;
2152 continue;
2153 }
Ted Kremenek5d304a32010-11-18 00:42:18 +00002154 case VisitorJob::MemberRefVisitKind: {
2155 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2156 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2157 return true;
2158 continue;
2159 }
Ted Kremenek92209a42010-11-11 08:05:18 +00002160 case VisitorJob::StmtVisitKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002161 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek7716cd62010-11-11 23:11:43 +00002162 if (!S)
2163 continue;
2164
Ted Kremenek73227d72010-11-12 18:26:56 +00002165 // Update the current cursor.
Ted Kremenek92209a42010-11-11 08:05:18 +00002166 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenek5d304a32010-11-18 00:42:18 +00002167 if (!IsInRegionOfInterest(Cursor))
2168 continue;
2169 switch (Visitor(Cursor, Parent, ClientData)) {
2170 case CXChildVisit_Break: return true;
2171 case CXChildVisit_Continue: break;
2172 case CXChildVisit_Recurse:
2173 EnqueueWorkList(WL, S);
Ted Kremeneke6f03042010-11-15 22:23:26 +00002174 break;
Ted Kremenek92209a42010-11-11 08:05:18 +00002175 }
Ted Kremeneke6f03042010-11-15 22:23:26 +00002176 continue;
Ted Kremenek92209a42010-11-11 08:05:18 +00002177 }
2178 case VisitorJob::MemberExprPartsKind: {
2179 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002180 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenek92209a42010-11-11 08:05:18 +00002181
2182 // Visit the nested-name-specifier
Douglas Gregorea972d32011-02-28 21:54:11 +00002183 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek92209a42010-11-11 08:05:18 +00002185 return true;
2186
2187 // Visit the declaration name.
2188 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2189 return true;
2190
2191 // Visit the explicitly-specified template arguments, if any.
2192 if (M->hasExplicitTemplateArgs()) {
2193 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2194 *ArgEnd = Arg + M->getNumTemplateArgs();
2195 Arg != ArgEnd; ++Arg) {
2196 if (VisitTemplateArgumentLoc(*Arg))
2197 return true;
2198 }
2199 }
2200 continue;
2201 }
Ted Kremenek573411b2010-11-13 00:58:18 +00002202 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002203 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremenek573411b2010-11-13 00:58:18 +00002204 // Visit nested-name-specifier, if present.
Douglas Gregorea972d32011-02-28 21:54:11 +00002205 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2206 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek573411b2010-11-13 00:58:18 +00002207 return true;
2208 // Visit declaration name.
2209 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2210 return true;
Ted Kremenek573411b2010-11-13 00:58:18 +00002211 continue;
2212 }
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002213 case VisitorJob::OverloadExprPartsKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002214 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002215 // Visit the nested-name-specifier.
Douglas Gregor0da1d432011-02-28 20:01:57 +00002216 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2217 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002218 return true;
2219 // Visit the declaration name.
2220 if (VisitDeclarationNameInfo(O->getNameInfo()))
2221 return true;
2222 // Visit the overloaded declaration reference.
2223 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2224 return true;
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002225 continue;
2226 }
Douglas Gregor557f05c2011-01-19 20:34:17 +00002227 case VisitorJob::SizeOfPackExprPartsKind: {
2228 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2229 NamedDecl *Pack = E->getPack();
2230 if (isa<TemplateTypeParmDecl>(Pack)) {
2231 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2232 E->getPackLoc(), TU)))
2233 return true;
2234
2235 continue;
2236 }
2237
2238 if (isa<TemplateTemplateParmDecl>(Pack)) {
2239 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2240 E->getPackLoc(), TU)))
2241 return true;
2242
2243 continue;
2244 }
2245
2246 // Non-type template parameter packs and function parameter packs are
2247 // treated like DeclRefExpr cursors.
2248 continue;
2249 }
Ted Kremenek92209a42010-11-11 08:05:18 +00002250 }
2251 }
2252 return false;
2253}
2254
Ted Kremenek5d304a32010-11-18 00:42:18 +00002255bool CursorVisitor::Visit(Stmt *S) {
Ted Kremeneka4c27ec2010-11-15 23:31:32 +00002256 VisitorWorkList *WL = 0;
2257 if (!WorkListFreeList.empty()) {
2258 WL = WorkListFreeList.back();
2259 WL->clear();
2260 WorkListFreeList.pop_back();
2261 }
2262 else {
2263 WL = new VisitorWorkList();
2264 WorkListCache.push_back(WL);
2265 }
2266 EnqueueWorkList(*WL, S);
2267 bool result = RunVisitorWorkList(*WL);
2268 WorkListFreeList.push_back(WL);
2269 return result;
Ted Kremenek92209a42010-11-11 08:05:18 +00002270}
2271
2272//===----------------------------------------------------------------------===//
2273// Misc. API hooks.
2274//===----------------------------------------------------------------------===//
2275
Douglas Gregor2c844822010-09-24 21:18:36 +00002276static llvm::sys::Mutex EnableMultithreadingMutex;
2277static bool EnabledMultithreading;
2278
Benjamin Kramer61f5d0c2009-10-18 16:11:04 +00002279extern "C" {
Douglas Gregor1e21cc72010-02-18 23:07:20 +00002280CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2281 int displayDiagnostics) {
Daniel Dunbara5af410d2010-10-08 19:30:33 +00002282 // Disable pretty stack trace functionality, which will otherwise be a very
2283 // poor citizen of the world and set up all sorts of signal handlers.
2284 llvm::DisablePrettyStackTrace = true;
2285
Daniel Dunbarc91f2ff2010-08-18 18:43:14 +00002286 // We use crash recovery to make some of our APIs more reliable, implicitly
2287 // enable it.
2288 llvm::CrashRecoveryContext::Enable();
2289
Douglas Gregor2c844822010-09-24 21:18:36 +00002290 // Enable support for multithreading in LLVM.
2291 {
2292 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2293 if (!EnabledMultithreading) {
2294 llvm::llvm_start_multithreaded();
2295 EnabledMultithreading = true;
2296 }
2297 }
2298
Douglas Gregor87752492010-01-22 20:35:53 +00002299 CIndexer *CIdxr = new CIndexer();
Steve Naroff531e2842009-10-20 14:46:24 +00002300 if (excludeDeclarationsFromPCH)
2301 CIdxr->setOnlyLocalDecls();
Douglas Gregor1e21cc72010-02-18 23:07:20 +00002302 if (displayDiagnostics)
2303 CIdxr->setDisplayDiagnostics();
Steve Naroff531e2842009-10-20 14:46:24 +00002304 return CIdxr;
Steve Naroffd5e8e862009-08-27 19:51:58 +00002305}
2306
Daniel Dunbar079203f2009-12-01 03:14:51 +00002307void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002308 if (CIdx)
2309 delete static_cast<CIndexer *>(CIdx);
Steve Naroff3aa2d732009-09-17 18:33:27 +00002310}
2311
Ted Kremenek1ec7b332011-03-18 23:05:39 +00002312void clang_toggleCrashRecovery(unsigned isEnabled) {
2313 if (isEnabled)
2314 llvm::CrashRecoveryContext::Enable();
2315 else
2316 llvm::CrashRecoveryContext::Disable();
2317}
2318
Daniel Dunbar079203f2009-12-01 03:14:51 +00002319CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002320 const char *ast_filename) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002321 if (!CIdx)
2322 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002323
Douglas Gregor16bef852009-10-16 20:01:17 +00002324 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis71731d62010-11-03 22:45:23 +00002325 FileSystemOptions FileSystemOpts;
2326 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002327
Douglas Gregor7f95d262010-04-05 23:52:57 +00002328 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremenek91554282010-11-16 08:15:36 +00002329 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002330 CXXIdx->getOnlyLocalDecls(),
2331 0, 0, true);
Ted Kremenek91554282010-11-16 08:15:36 +00002332 return MakeCXTranslationUnit(TU);
Steve Naroffd5e8e862009-08-27 19:51:58 +00002333}
2334
Douglas Gregor4a47bca2010-08-09 22:28:58 +00002335unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor176d2862010-09-27 05:49:58 +00002336 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregorf5a18542010-10-27 17:24:53 +00002337 CXTranslationUnit_CacheCompletionResults |
2338 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregor4a47bca2010-08-09 22:28:58 +00002339}
2340
Daniel Dunbar079203f2009-12-01 03:14:51 +00002341CXTranslationUnit
2342clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2343 const char *source_filename,
2344 int num_command_line_args,
Douglas Gregor57879fa2010-09-01 16:43:19 +00002345 const char * const *command_line_args,
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002346 unsigned num_unsaved_files,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002347 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor99d2cf42010-07-21 18:52:53 +00002348 return clang_parseTranslationUnit(CIdx, source_filename,
2349 command_line_args, num_command_line_args,
2350 unsaved_files, num_unsaved_files,
2351 CXTranslationUnit_DetailedPreprocessingRecord);
2352}
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002353
2354struct ParseTranslationUnitInfo {
2355 CXIndex CIdx;
2356 const char *source_filename;
Douglas Gregor57879fa2010-09-01 16:43:19 +00002357 const char *const *command_line_args;
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002358 int num_command_line_args;
2359 struct CXUnsavedFile *unsaved_files;
2360 unsigned num_unsaved_files;
2361 unsigned options;
2362 CXTranslationUnit result;
2363};
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002364static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002365 ParseTranslationUnitInfo *PTUI =
2366 static_cast<ParseTranslationUnitInfo*>(UserData);
2367 CXIndex CIdx = PTUI->CIdx;
2368 const char *source_filename = PTUI->source_filename;
Douglas Gregor57879fa2010-09-01 16:43:19 +00002369 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002370 int num_command_line_args = PTUI->num_command_line_args;
2371 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2372 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2373 unsigned options = PTUI->options;
2374 PTUI->result = 0;
Douglas Gregor99d2cf42010-07-21 18:52:53 +00002375
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002376 if (!CIdx)
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002377 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002378
Steve Naroff531e2842009-10-20 14:46:24 +00002379 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2380
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002381 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregor028d3e42010-08-09 20:45:32 +00002382 bool CompleteTranslationUnit
2383 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregorb14904c2010-08-13 22:48:40 +00002384 bool CacheCodeCompetionResults
2385 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregorf5a18542010-10-27 17:24:53 +00002386 bool CXXPrecompilePreamble
2387 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2388 bool CXXChainedPCH
2389 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregorb14904c2010-08-13 22:48:40 +00002390
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002391 // Configure the diagnostics.
2392 DiagnosticOptions DiagOpts;
Ted Kremenek022a4902011-03-22 01:15:24 +00002393 llvm::IntrusiveRefCntPtr<Diagnostic>
2394 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2395 command_line_args));
Ted Kremenekf441baf2010-02-17 00:41:40 +00002396
Ted Kremenek022a4902011-03-22 01:15:24 +00002397 // Recover resources if we crash before exiting this function.
2398 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2399 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2400 DiagCleanup(Diags.getPtr());
2401
2402 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2403 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2404
2405 // Recover resources if we crash before exiting this function.
2406 llvm::CrashRecoveryContextCleanupRegistrar<
2407 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2408
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002409 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattner58c79342010-04-05 22:42:27 +00002410 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002411 const llvm::MemoryBuffer *Buffer
Chris Lattner58c79342010-04-05 22:42:27 +00002412 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek022a4902011-03-22 01:15:24 +00002413 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2414 Buffer));
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002415 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00002416
Ted Kremenek022a4902011-03-22 01:15:24 +00002417 llvm::OwningPtr<std::vector<const char *> >
2418 Args(new std::vector<const char*>());
2419
2420 // Recover resources if we crash before exiting this method.
2421 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2422 ArgsCleanup(Args.get());
2423
Douglas Gregor79edde82010-07-09 18:39:07 +00002424 // Since the Clang C library is primarily used by batch tools dealing with
2425 // (often very broken) source code, where spell-checking can have a
2426 // significant negative impact on performance (particularly when
2427 // precompiled headers are involved), we disable it by default.
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002428 // Only do this if we haven't found a spell-checking-related argument.
2429 bool FoundSpellCheckingArgument = false;
2430 for (int I = 0; I != num_command_line_args; ++I) {
2431 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2432 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2433 FoundSpellCheckingArgument = true;
2434 break;
Steve Naroff531e2842009-10-20 14:46:24 +00002435 }
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002436 }
2437 if (!FoundSpellCheckingArgument)
Ted Kremenek022a4902011-03-22 01:15:24 +00002438 Args->push_back("-fno-spell-checking");
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002439
Ted Kremenek022a4902011-03-22 01:15:24 +00002440 Args->insert(Args->end(), command_line_args,
2441 command_line_args + num_command_line_args);
Douglas Gregorac0605e2010-01-28 06:00:51 +00002442
Argyrios Kyrtzidise7620202011-03-20 18:17:52 +00002443 // The 'source_filename' argument is optional. If the caller does not
2444 // specify it then it is assumed that the source file is specified
2445 // in the actual argument list.
2446 // Put the source file after command_line_args otherwise if '-x' flag is
2447 // present it will be unused.
2448 if (source_filename)
Ted Kremenek022a4902011-03-22 01:15:24 +00002449 Args->push_back(source_filename);
Argyrios Kyrtzidise7620202011-03-20 18:17:52 +00002450
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002451 // Do we need the detailed preprocessing record?
2452 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek022a4902011-03-22 01:15:24 +00002453 Args->push_back("-Xclang");
2454 Args->push_back("-detailed-preprocessing-record");
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002455 }
2456
Argyrios Kyrtzidis8d5038c2010-11-18 21:47:04 +00002457 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002458 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek600b54c2011-03-22 20:16:19 +00002459 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2460 /* vector::data() not portable */,
2461 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002462 Diags,
2463 CXXIdx->getClangResourcesPath(),
2464 CXXIdx->getOnlyLocalDecls(),
Douglas Gregor44c6ee72010-11-11 00:39:14 +00002465 /*CaptureDiagnostics=*/true,
Ted Kremenek600b54c2011-03-22 20:16:19 +00002466 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek022a4902011-03-22 01:15:24 +00002467 RemappedFiles->size(),
Argyrios Kyrtzidis97d3a382011-03-08 23:35:24 +00002468 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002469 PrecompilePreamble,
2470 CompleteTranslationUnit,
Douglas Gregorf5a18542010-10-27 17:24:53 +00002471 CacheCodeCompetionResults,
2472 CXXPrecompilePreamble,
2473 CXXChainedPCH));
Ted Kremenekf441baf2010-02-17 00:41:40 +00002474
Argyrios Kyrtzidis8d5038c2010-11-18 21:47:04 +00002475 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002476 // Make sure to check that 'Unit' is non-NULL.
2477 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2478 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2479 DEnd = Unit->stored_diag_end();
2480 D != DEnd; ++D) {
2481 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2482 CXString Msg = clang_formatDiagnostic(&Diag,
2483 clang_defaultDiagnosticDisplayOptions());
2484 fprintf(stderr, "%s\n", clang_getCString(Msg));
2485 clang_disposeString(Msg);
2486 }
Douglas Gregord770f732010-02-22 23:17:23 +00002487#ifdef LLVM_ON_WIN32
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002488 // On Windows, force a flush, since there may be multiple copies of
2489 // stderr and stdout in the file system, all with different buffers
2490 // but writing to the same device.
2491 fflush(stderr);
2492#endif
2493 }
Douglas Gregor33cdd812010-02-18 18:08:43 +00002494 }
Douglas Gregorac0605e2010-01-28 06:00:51 +00002495
Ted Kremenek91554282010-11-16 08:15:36 +00002496 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002497}
2498CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2499 const char *source_filename,
Douglas Gregor57879fa2010-09-01 16:43:19 +00002500 const char * const *command_line_args,
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002501 int num_command_line_args,
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002502 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002503 unsigned num_unsaved_files,
2504 unsigned options) {
2505 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002506 num_command_line_args, unsaved_files,
2507 num_unsaved_files, options, 0 };
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002508 llvm::CrashRecoveryContext CRC;
2509
Daniel Dunbarb7383e62010-11-05 07:19:31 +00002510 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbarf10f9be2010-08-23 22:35:34 +00002511 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2512 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2513 fprintf(stderr, " 'command_line_args' : [");
2514 for (int i = 0; i != num_command_line_args; ++i) {
2515 if (i)
2516 fprintf(stderr, ", ");
2517 fprintf(stderr, "'%s'", command_line_args[i]);
2518 }
2519 fprintf(stderr, "],\n");
2520 fprintf(stderr, " 'unsaved_files' : [");
2521 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2522 if (i)
2523 fprintf(stderr, ", ");
2524 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2525 unsaved_files[i].Length);
2526 }
2527 fprintf(stderr, "],\n");
2528 fprintf(stderr, " 'options' : %d,\n", options);
2529 fprintf(stderr, "}\n");
2530
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002531 return 0;
2532 }
2533
2534 return PTUI.result;
Steve Naroff7781daa2009-10-15 20:04:39 +00002535}
2536
Douglas Gregor6bb92ec2010-08-13 15:35:05 +00002537unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2538 return CXSaveTranslationUnit_None;
2539}
2540
2541int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2542 unsigned options) {
Douglas Gregore9386682010-08-13 05:36:37 +00002543 if (!TU)
2544 return 1;
2545
Ted Kremenek91554282010-11-16 08:15:36 +00002546 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregore9386682010-08-13 05:36:37 +00002547}
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002548
Daniel Dunbar079203f2009-12-01 03:14:51 +00002549void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002550 if (CTUnit) {
2551 // If the translation unit has been marked as unsafe to free, just discard
2552 // it.
Ted Kremenek91554282010-11-16 08:15:36 +00002553 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002554 return;
2555
Ted Kremenek91554282010-11-16 08:15:36 +00002556 delete static_cast<ASTUnit *>(CTUnit->TUData);
2557 disposeCXStringPool(CTUnit->StringPool);
2558 delete CTUnit;
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002559 }
Steve Naroff3aa2d732009-09-17 18:33:27 +00002560}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002561
Douglas Gregorde051182010-08-11 15:58:42 +00002562unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2563 return CXReparse_None;
2564}
2565
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002566struct ReparseTranslationUnitInfo {
2567 CXTranslationUnit TU;
2568 unsigned num_unsaved_files;
2569 struct CXUnsavedFile *unsaved_files;
2570 unsigned options;
2571 int result;
2572};
Douglas Gregorca5b0532010-09-23 18:47:53 +00002573
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002574static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002575 ReparseTranslationUnitInfo *RTUI =
2576 static_cast<ReparseTranslationUnitInfo*>(UserData);
2577 CXTranslationUnit TU = RTUI->TU;
2578 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2579 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2580 unsigned options = RTUI->options;
2581 (void) options;
2582 RTUI->result = 1;
2583
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002584 if (!TU)
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002585 return;
Douglas Gregorca5b0532010-09-23 18:47:53 +00002586
Ted Kremenek91554282010-11-16 08:15:36 +00002587 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorca5b0532010-09-23 18:47:53 +00002588 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002589
Ted Kremenek022a4902011-03-22 01:15:24 +00002590 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2591 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2592
2593 // Recover resources if we crash before exiting this function.
2594 llvm::CrashRecoveryContextCleanupRegistrar<
2595 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2596
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002597 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2598 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2599 const llvm::MemoryBuffer *Buffer
Douglas Gregor8e984da2010-08-04 16:47:14 +00002600 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek022a4902011-03-22 01:15:24 +00002601 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2602 Buffer));
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002603 }
2604
Ted Kremenek600b54c2011-03-22 20:16:19 +00002605 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2606 RemappedFiles->size()))
Douglas Gregorca5b0532010-09-23 18:47:53 +00002607 RTUI->result = 0;
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002608}
Douglas Gregorca5b0532010-09-23 18:47:53 +00002609
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002610int clang_reparseTranslationUnit(CXTranslationUnit TU,
2611 unsigned num_unsaved_files,
2612 struct CXUnsavedFile *unsaved_files,
2613 unsigned options) {
2614 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2615 options, 0 };
2616 llvm::CrashRecoveryContext CRC;
2617
Daniel Dunbarb7383e62010-11-05 07:19:31 +00002618 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002619 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremenek91554282010-11-16 08:15:36 +00002620 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002621 return 1;
2622 }
2623
Ted Kremenek55ccf4e2010-10-29 01:06:50 +00002624
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002625 return RTUI.result;
2626}
2627
Douglas Gregor028d3e42010-08-09 20:45:32 +00002628
Daniel Dunbar079203f2009-12-01 03:14:51 +00002629CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002630 if (!CTUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002631 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00002632
Ted Kremenek91554282010-11-16 08:15:36 +00002633 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002634 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroff38c1a7b2009-09-03 15:49:00 +00002635}
Daniel Dunbare58bd8b2009-08-28 16:30:07 +00002636
Douglas Gregord2fc7272010-01-20 00:23:15 +00002637CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00002638 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregord2fc7272010-01-20 00:23:15 +00002639 return Result;
2640}
2641
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002642} // end: extern "C"
Steve Naroffd5e8e862009-08-27 19:51:58 +00002643
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002644//===----------------------------------------------------------------------===//
Douglas Gregor4f46e782010-01-19 21:36:55 +00002645// CXSourceLocation and CXSourceRange Operations.
2646//===----------------------------------------------------------------------===//
2647
Douglas Gregor816fd362010-01-22 21:44:22 +00002648extern "C" {
2649CXSourceLocation clang_getNullLocation() {
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002650 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregor816fd362010-01-22 21:44:22 +00002651 return Result;
2652}
2653
2654unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar83a23542010-01-30 23:58:27 +00002655 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2656 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2657 loc1.int_data == loc2.int_data);
Douglas Gregor816fd362010-01-22 21:44:22 +00002658}
2659
2660CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2661 CXFile file,
2662 unsigned line,
2663 unsigned column) {
Douglas Gregor0925fbc2010-04-30 19:45:53 +00002664 if (!tu || !file)
Douglas Gregor816fd362010-01-22 21:44:22 +00002665 return clang_getNullLocation();
Douglas Gregor0925fbc2010-04-30 19:45:53 +00002666
Douglas Gregore6642762011-02-03 17:17:35 +00002667 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremenek91554282010-11-16 08:15:36 +00002668 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregore6642762011-02-03 17:17:35 +00002669 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregor816fd362010-01-22 21:44:22 +00002670 SourceLocation SLoc
Douglas Gregore6642762011-02-03 17:17:35 +00002671 = CXXUnit->getSourceManager().getLocation(File, line, column);
2672 if (SLoc.isInvalid()) {
2673 if (Logging)
2674 llvm::errs() << "clang_getLocation(\"" << File->getName()
2675 << "\", " << line << ", " << column << ") = invalid\n";
2676 return clang_getNullLocation();
2677 }
2678
2679 if (Logging)
2680 llvm::errs() << "clang_getLocation(\"" << File->getName()
2681 << "\", " << line << ", " << column << ") = "
2682 << SLoc.getRawEncoding() << "\n";
David Chisnall2e16ac52010-10-15 17:07:39 +00002683
2684 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2685}
2686
2687CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2688 CXFile file,
2689 unsigned offset) {
2690 if (!tu || !file)
2691 return clang_getNullLocation();
2692
Ted Kremenek91554282010-11-16 08:15:36 +00002693 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall2e16ac52010-10-15 17:07:39 +00002694 SourceLocation Start
2695 = CXXUnit->getSourceManager().getLocation(
2696 static_cast<const FileEntry *>(file),
2697 1, 1);
2698 if (Start.isInvalid()) return clang_getNullLocation();
2699
2700 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2701
2702 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002703
Ted Kremenek54140272010-06-28 23:54:17 +00002704 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregor816fd362010-01-22 21:44:22 +00002705}
2706
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002707CXSourceRange clang_getNullRange() {
2708 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2709 return Result;
2710}
Daniel Dunbar02968e52010-02-14 10:02:57 +00002711
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002712CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2713 if (begin.ptr_data[0] != end.ptr_data[0] ||
2714 begin.ptr_data[1] != end.ptr_data[1])
2715 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002716
2717 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002718 begin.int_data, end.int_data };
Douglas Gregor816fd362010-01-22 21:44:22 +00002719 return Result;
2720}
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002721} // end: extern "C"
Douglas Gregor816fd362010-01-22 21:44:22 +00002722
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002723static void createNullLocation(CXFile *file, unsigned *line,
2724 unsigned *column, unsigned *offset) {
2725 if (file)
2726 *file = 0;
2727 if (line)
2728 *line = 0;
2729 if (column)
2730 *column = 0;
2731 if (offset)
2732 *offset = 0;
2733 return;
2734}
2735
2736extern "C" {
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002737void clang_getInstantiationLocation(CXSourceLocation location,
2738 CXFile *file,
2739 unsigned *line,
2740 unsigned *column,
2741 unsigned *offset) {
Douglas Gregor4f46e782010-01-19 21:36:55 +00002742 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2743
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002744 if (!location.ptr_data[0] || Loc.isInvalid()) {
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002745 createNullLocation(file, line, column, offset);
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002746 return;
2747 }
2748
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002749 const SourceManager &SM =
2750 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002751 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002752
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002753 // Check that the FileID is invalid on the instantiation location.
2754 // This can manifest in invalid code.
2755 FileID fileID = SM.getFileID(InstLoc);
2756 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID);
2757 if (!sloc.isFile()) {
2758 createNullLocation(file, line, column, offset);
2759 return;
2760 }
2761
Douglas Gregor4f46e782010-01-19 21:36:55 +00002762 if (file)
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002763 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002764 if (line)
2765 *line = SM.getInstantiationLineNumber(InstLoc);
2766 if (column)
2767 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregor47751d62010-01-26 03:07:15 +00002768 if (offset)
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002769 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregor47751d62010-01-26 03:07:15 +00002770}
2771
Douglas Gregor229bebd2010-11-09 06:24:54 +00002772void clang_getSpellingLocation(CXSourceLocation location,
2773 CXFile *file,
2774 unsigned *line,
2775 unsigned *column,
2776 unsigned *offset) {
2777 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2778
2779 if (!location.ptr_data[0] || Loc.isInvalid()) {
2780 if (file)
2781 *file = 0;
2782 if (line)
2783 *line = 0;
2784 if (column)
2785 *column = 0;
2786 if (offset)
2787 *offset = 0;
2788 return;
2789 }
2790
2791 const SourceManager &SM =
2792 *static_cast<const SourceManager*>(location.ptr_data[0]);
2793 SourceLocation SpellLoc = Loc;
2794 if (SpellLoc.isMacroID()) {
2795 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2796 if (SimpleSpellingLoc.isFileID() &&
2797 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2798 SpellLoc = SimpleSpellingLoc;
2799 else
2800 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2801 }
2802
2803 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2804 FileID FID = LocInfo.first;
2805 unsigned FileOffset = LocInfo.second;
2806
2807 if (file)
2808 *file = (void *)SM.getFileEntryForID(FID);
2809 if (line)
2810 *line = SM.getLineNumber(FID, FileOffset);
2811 if (column)
2812 *column = SM.getColumnNumber(FID, FileOffset);
2813 if (offset)
2814 *offset = FileOffset;
2815}
2816
Douglas Gregor4f46e782010-01-19 21:36:55 +00002817CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002818 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002819 range.begin_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002820 return Result;
2821}
2822
2823CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002824 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002825 range.end_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002826 return Result;
2827}
2828
Douglas Gregor816fd362010-01-22 21:44:22 +00002829} // end: extern "C"
2830
Douglas Gregor4f46e782010-01-19 21:36:55 +00002831//===----------------------------------------------------------------------===//
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002832// CXFile Operations.
2833//===----------------------------------------------------------------------===//
2834
2835extern "C" {
Ted Kremenekc560b682010-02-17 00:41:20 +00002836CXString clang_getFileName(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002837 if (!SFile)
Ted Kremenek91554282010-11-16 08:15:36 +00002838 return createCXString((const char*)NULL);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002839
Steve Naroff6231f182009-10-27 14:35:18 +00002840 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenekc560b682010-02-17 00:41:20 +00002841 return createCXString(FEnt->getName());
Steve Naroff6231f182009-10-27 14:35:18 +00002842}
2843
2844time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002845 if (!SFile)
2846 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002847
Steve Naroff6231f182009-10-27 14:35:18 +00002848 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2849 return FEnt->getModificationTime();
Steve Naroff26760892009-09-25 21:45:39 +00002850}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002851
Douglas Gregor816fd362010-01-22 21:44:22 +00002852CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2853 if (!tu)
2854 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002855
Ted Kremenek91554282010-11-16 08:15:36 +00002856 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002857
Douglas Gregor816fd362010-01-22 21:44:22 +00002858 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner5159f612010-11-23 08:35:12 +00002859 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregor816fd362010-01-22 21:44:22 +00002860}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002861
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002862} // end: extern "C"
Steve Naroff26760892009-09-25 21:45:39 +00002863
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002864//===----------------------------------------------------------------------===//
2865// CXCursor Operations.
2866//===----------------------------------------------------------------------===//
2867
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002868static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregore6712982010-10-01 21:11:22 +00002869 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2870 return getDeclFromExpr(CE->getSubExpr());
2871
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002872 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2873 return RefExpr->getDecl();
Douglas Gregor263803a2010-10-22 22:24:08 +00002874 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2875 return RefExpr->getDecl();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002876 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2877 return ME->getMemberDecl();
2878 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2879 return RE->getDecl();
Douglas Gregore6712982010-10-01 21:11:22 +00002880 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCallb7bd14f2010-12-02 01:19:52 +00002881 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregore6712982010-10-01 21:11:22 +00002882
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002883 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2884 return getDeclFromExpr(CE->getCallee());
Douglas Gregor16443fd2010-11-05 21:11:19 +00002885 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2886 if (!CE->isElidable())
2887 return CE->getConstructor();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002888 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2889 return OME->getMethodDecl();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002890
Douglas Gregore6712982010-10-01 21:11:22 +00002891 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2892 return PE->getProtocol();
Douglas Gregorcdbc5392011-01-15 01:15:58 +00002893 if (SubstNonTypeTemplateParmPackExpr *NTTP
2894 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2895 return NTTP->getParameterPack();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002896 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2897 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2898 isa<ParmVarDecl>(SizeOfPack->getPack()))
2899 return SizeOfPack->getPack();
Douglas Gregore6712982010-10-01 21:11:22 +00002900
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002901 return 0;
2902}
2903
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002904static SourceLocation getLocationFromExpr(Expr *E) {
2905 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2906 return /*FIXME:*/Msg->getLeftLoc();
2907 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2908 return DRE->getLocation();
Douglas Gregor263803a2010-10-22 22:24:08 +00002909 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2910 return RefExpr->getLocation();
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002911 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2912 return Member->getMemberLoc();
2913 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2914 return Ivar->getLocation();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002915 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2916 return SizeOfPack->getPackLoc();
2917
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002918 return E->getLocStart();
2919}
2920
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002921extern "C" {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002922
2923unsigned clang_visitChildren(CXCursor parent,
Douglas Gregor71f3d942010-01-20 20:59:29 +00002924 CXCursorVisitor visitor,
2925 CXClientData client_data) {
Ted Kremenek91554282010-11-16 08:15:36 +00002926 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregorc2b97992011-03-16 23:23:30 +00002927 getCursorASTUnit(parent)->getMaxPCHLevel(),
2928 false);
Douglas Gregor71f3d942010-01-20 20:59:29 +00002929 return CursorVis.VisitChildren(parent);
2930}
2931
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002932#ifndef __has_feature
2933#define __has_feature(x) 0
2934#endif
2935#if __has_feature(blocks)
2936typedef enum CXChildVisitResult
2937 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2938
2939static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2940 CXClientData client_data) {
2941 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2942 return block(cursor, parent);
2943}
2944#else
2945// If we are compiled with a compiler that doesn't have native blocks support,
2946// define and call the block manually, so the
2947typedef struct _CXChildVisitResult
2948{
2949 void *isa;
2950 int flags;
2951 int reserved;
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002952 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2953 CXCursor);
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002954} *CXCursorVisitorBlock;
2955
2956static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2957 CXClientData client_data) {
2958 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2959 return block->invoke(block, cursor, parent);
2960}
2961#endif
2962
2963
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002964unsigned clang_visitChildrenWithBlock(CXCursor parent,
2965 CXCursorVisitorBlock block) {
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002966 return clang_visitChildren(parent, visitWithBlock, block);
2967}
2968
Douglas Gregordd969c82010-01-20 21:45:58 +00002969static CXString getDeclSpelling(Decl *D) {
2970 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002971 if (!ND) {
2972 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2973 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2974 return createCXString(Property->getIdentifier()->getName());
2975
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002976 return createCXString("");
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002977 }
2978
Douglas Gregordd969c82010-01-20 21:45:58 +00002979 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002980 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf441baf2010-02-17 00:41:40 +00002981
Douglas Gregordd969c82010-01-20 21:45:58 +00002982 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2983 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2984 // and returns different names. NamedDecl returns the class name and
2985 // ObjCCategoryImplDecl returns the category name.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002986 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf441baf2010-02-17 00:41:40 +00002987
Douglas Gregor01a430132010-09-01 03:07:18 +00002988 if (isa<UsingDirectiveDecl>(D))
2989 return createCXString("");
2990
Ted Kremenek08de5c12010-05-19 21:51:10 +00002991 llvm::SmallString<1024> S;
2992 llvm::raw_svector_ostream os(S);
2993 ND->printName(os);
2994
2995 return createCXString(os.str());
Douglas Gregordd969c82010-01-20 21:45:58 +00002996}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002997
Daniel Dunbar079203f2009-12-01 03:14:51 +00002998CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregord2fc7272010-01-20 00:23:15 +00002999 if (clang_isTranslationUnit(C.kind))
Ted Kremenek91554282010-11-16 08:15:36 +00003000 return clang_getTranslationUnitSpelling(
3001 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregord2fc7272010-01-20 00:23:15 +00003002
Steve Naroff80a766b2009-09-02 18:26:48 +00003003 if (clang_isReference(C.kind)) {
3004 switch (C.kind) {
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003005 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor6c8959b2010-01-16 14:00:32 +00003006 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003007 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003008 }
3009 case CXCursor_ObjCClassRef: {
Douglas Gregor46d66142010-01-16 17:14:40 +00003010 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003011 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003012 }
3013 case CXCursor_ObjCProtocolRef: {
Douglas Gregoref6eb842010-01-16 15:44:18 +00003014 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003015 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003016 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003017 }
Ted Kremenekae9e2212010-08-27 21:34:58 +00003018 case CXCursor_CXXBaseSpecifier: {
3019 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3020 return createCXString(B->getType().getAsString());
3021 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003022 case CXCursor_TypeRef: {
3023 TypeDecl *Type = getCursorTypeRef(C).first;
3024 assert(Type && "Missing type decl");
3025
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003026 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3027 getAsString());
Douglas Gregor93f89952010-01-21 16:28:34 +00003028 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00003029 case CXCursor_TemplateRef: {
3030 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregora89314e2010-08-31 23:48:11 +00003031 assert(Template && "Missing template decl");
Douglas Gregora23e8f72010-08-31 20:37:03 +00003032
3033 return createCXString(Template->getNameAsString());
3034 }
Douglas Gregora89314e2010-08-31 23:48:11 +00003035
3036 case CXCursor_NamespaceRef: {
3037 NamedDecl *NS = getCursorNamespaceRef(C).first;
3038 assert(NS && "Missing namespace decl");
3039
3040 return createCXString(NS->getNameAsString());
3041 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003042
Douglas Gregorf3af3112010-09-09 21:42:20 +00003043 case CXCursor_MemberRef: {
3044 FieldDecl *Field = getCursorMemberRef(C).first;
3045 assert(Field && "Missing member decl");
3046
3047 return createCXString(Field->getNameAsString());
3048 }
3049
Douglas Gregora93ab662010-09-10 00:22:18 +00003050 case CXCursor_LabelRef: {
3051 LabelStmt *Label = getCursorLabelRef(C).first;
3052 assert(Label && "Missing label");
3053
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003054 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00003055 }
3056
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003057 case CXCursor_OverloadedDeclRef: {
3058 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3059 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3060 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3061 return createCXString(ND->getNameAsString());
3062 return createCXString("");
3063 }
3064 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3065 return createCXString(E->getName().getAsString());
3066 OverloadedTemplateStorage *Ovl
3067 = Storage.get<OverloadedTemplateStorage*>();
3068 if (Ovl->size() == 0)
3069 return createCXString("");
3070 return createCXString((*Ovl->begin())->getNameAsString());
3071 }
3072
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003073 default:
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003074 return createCXString("<not implemented>");
Steve Naroff80a766b2009-09-02 18:26:48 +00003075 }
3076 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003077
3078 if (clang_isExpression(C.kind)) {
3079 Decl *D = getDeclFromExpr(getCursorExpr(C));
3080 if (D)
Douglas Gregordd969c82010-01-20 21:45:58 +00003081 return getDeclSpelling(D);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003082 return createCXString("");
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003083 }
3084
Douglas Gregora93ab662010-09-10 00:22:18 +00003085 if (clang_isStatement(C.kind)) {
3086 Stmt *S = getCursorStmt(C);
3087 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003088 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00003089
3090 return createCXString("");
3091 }
3092
Douglas Gregor065f8d12010-03-18 17:52:52 +00003093 if (C.kind == CXCursor_MacroInstantiation)
3094 return createCXString(getCursorMacroInstantiation(C)->getName()
3095 ->getNameStart());
3096
Douglas Gregor06d6d322010-03-18 18:04:21 +00003097 if (C.kind == CXCursor_MacroDefinition)
3098 return createCXString(getCursorMacroDefinition(C)->getName()
3099 ->getNameStart());
3100
Douglas Gregor796d76a2010-10-20 22:00:55 +00003101 if (C.kind == CXCursor_InclusionDirective)
3102 return createCXString(getCursorInclusionDirective(C)->getFileName());
3103
Douglas Gregor5bce76c2010-01-25 16:56:17 +00003104 if (clang_isDeclaration(C.kind))
3105 return getDeclSpelling(getCursorDecl(C));
Ted Kremenek29004672010-02-17 00:41:32 +00003106
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003107 return createCXString("");
Steve Naroff80a766b2009-09-02 18:26:48 +00003108}
3109
Douglas Gregor97c75712010-10-02 22:49:11 +00003110CXString clang_getCursorDisplayName(CXCursor C) {
3111 if (!clang_isDeclaration(C.kind))
3112 return clang_getCursorSpelling(C);
3113
3114 Decl *D = getCursorDecl(C);
3115 if (!D)
3116 return createCXString("");
3117
3118 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3119 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3120 D = FunTmpl->getTemplatedDecl();
3121
3122 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3123 llvm::SmallString<64> Str;
3124 llvm::raw_svector_ostream OS(Str);
3125 OS << Function->getNameAsString();
3126 if (Function->getPrimaryTemplate())
3127 OS << "<>";
3128 OS << "(";
3129 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3130 if (I)
3131 OS << ", ";
3132 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3133 }
3134
3135 if (Function->isVariadic()) {
3136 if (Function->getNumParams())
3137 OS << ", ";
3138 OS << "...";
3139 }
3140 OS << ")";
3141 return createCXString(OS.str());
3142 }
3143
3144 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3145 llvm::SmallString<64> Str;
3146 llvm::raw_svector_ostream OS(Str);
3147 OS << ClassTemplate->getNameAsString();
3148 OS << "<";
3149 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3150 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3151 if (I)
3152 OS << ", ";
3153
3154 NamedDecl *Param = Params->getParam(I);
3155 if (Param->getIdentifier()) {
3156 OS << Param->getIdentifier()->getName();
3157 continue;
3158 }
3159
3160 // There is no parameter name, which makes this tricky. Try to come up
3161 // with something useful that isn't too long.
3162 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3163 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3164 else if (NonTypeTemplateParmDecl *NTTP
3165 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3166 OS << NTTP->getType().getAsString(Policy);
3167 else
3168 OS << "template<...> class";
3169 }
3170
3171 OS << ">";
3172 return createCXString(OS.str());
3173 }
3174
3175 if (ClassTemplateSpecializationDecl *ClassSpec
3176 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3177 // If the type was explicitly written, use that.
3178 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3179 return createCXString(TSInfo->getType().getAsString(Policy));
3180
3181 llvm::SmallString<64> Str;
3182 llvm::raw_svector_ostream OS(Str);
3183 OS << ClassSpec->getNameAsString();
3184 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor1ccc8412010-11-07 23:05:16 +00003185 ClassSpec->getTemplateArgs().data(),
3186 ClassSpec->getTemplateArgs().size(),
Douglas Gregor97c75712010-10-02 22:49:11 +00003187 Policy);
3188 return createCXString(OS.str());
3189 }
3190
3191 return clang_getCursorSpelling(C);
3192}
3193
Ted Kremenek29004672010-02-17 00:41:32 +00003194CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff1054e602009-08-31 00:59:03 +00003195 switch (Kind) {
Ted Kremenek29004672010-02-17 00:41:32 +00003196 case CXCursor_FunctionDecl:
3197 return createCXString("FunctionDecl");
3198 case CXCursor_TypedefDecl:
3199 return createCXString("TypedefDecl");
3200 case CXCursor_EnumDecl:
3201 return createCXString("EnumDecl");
3202 case CXCursor_EnumConstantDecl:
3203 return createCXString("EnumConstantDecl");
3204 case CXCursor_StructDecl:
3205 return createCXString("StructDecl");
3206 case CXCursor_UnionDecl:
3207 return createCXString("UnionDecl");
3208 case CXCursor_ClassDecl:
3209 return createCXString("ClassDecl");
3210 case CXCursor_FieldDecl:
3211 return createCXString("FieldDecl");
3212 case CXCursor_VarDecl:
3213 return createCXString("VarDecl");
3214 case CXCursor_ParmDecl:
3215 return createCXString("ParmDecl");
3216 case CXCursor_ObjCInterfaceDecl:
3217 return createCXString("ObjCInterfaceDecl");
3218 case CXCursor_ObjCCategoryDecl:
3219 return createCXString("ObjCCategoryDecl");
3220 case CXCursor_ObjCProtocolDecl:
3221 return createCXString("ObjCProtocolDecl");
3222 case CXCursor_ObjCPropertyDecl:
3223 return createCXString("ObjCPropertyDecl");
3224 case CXCursor_ObjCIvarDecl:
3225 return createCXString("ObjCIvarDecl");
3226 case CXCursor_ObjCInstanceMethodDecl:
3227 return createCXString("ObjCInstanceMethodDecl");
3228 case CXCursor_ObjCClassMethodDecl:
3229 return createCXString("ObjCClassMethodDecl");
3230 case CXCursor_ObjCImplementationDecl:
3231 return createCXString("ObjCImplementationDecl");
3232 case CXCursor_ObjCCategoryImplDecl:
3233 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek225b8e32010-04-13 23:39:06 +00003234 case CXCursor_CXXMethod:
3235 return createCXString("CXXMethod");
Ted Kremenek29004672010-02-17 00:41:32 +00003236 case CXCursor_UnexposedDecl:
3237 return createCXString("UnexposedDecl");
3238 case CXCursor_ObjCSuperClassRef:
3239 return createCXString("ObjCSuperClassRef");
3240 case CXCursor_ObjCProtocolRef:
3241 return createCXString("ObjCProtocolRef");
3242 case CXCursor_ObjCClassRef:
3243 return createCXString("ObjCClassRef");
3244 case CXCursor_TypeRef:
3245 return createCXString("TypeRef");
Douglas Gregora23e8f72010-08-31 20:37:03 +00003246 case CXCursor_TemplateRef:
3247 return createCXString("TemplateRef");
Douglas Gregora89314e2010-08-31 23:48:11 +00003248 case CXCursor_NamespaceRef:
3249 return createCXString("NamespaceRef");
Douglas Gregorf3af3112010-09-09 21:42:20 +00003250 case CXCursor_MemberRef:
3251 return createCXString("MemberRef");
Douglas Gregora93ab662010-09-10 00:22:18 +00003252 case CXCursor_LabelRef:
3253 return createCXString("LabelRef");
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003254 case CXCursor_OverloadedDeclRef:
3255 return createCXString("OverloadedDeclRef");
Ted Kremenek29004672010-02-17 00:41:32 +00003256 case CXCursor_UnexposedExpr:
3257 return createCXString("UnexposedExpr");
Ted Kremenek33b9a422010-04-11 21:47:37 +00003258 case CXCursor_BlockExpr:
3259 return createCXString("BlockExpr");
Ted Kremenek29004672010-02-17 00:41:32 +00003260 case CXCursor_DeclRefExpr:
3261 return createCXString("DeclRefExpr");
3262 case CXCursor_MemberRefExpr:
3263 return createCXString("MemberRefExpr");
3264 case CXCursor_CallExpr:
3265 return createCXString("CallExpr");
3266 case CXCursor_ObjCMessageExpr:
3267 return createCXString("ObjCMessageExpr");
3268 case CXCursor_UnexposedStmt:
3269 return createCXString("UnexposedStmt");
Douglas Gregora93ab662010-09-10 00:22:18 +00003270 case CXCursor_LabelStmt:
3271 return createCXString("LabelStmt");
Ted Kremenek29004672010-02-17 00:41:32 +00003272 case CXCursor_InvalidFile:
3273 return createCXString("InvalidFile");
Ted Kremenek00da3b92010-03-19 20:39:05 +00003274 case CXCursor_InvalidCode:
3275 return createCXString("InvalidCode");
Ted Kremenek29004672010-02-17 00:41:32 +00003276 case CXCursor_NoDeclFound:
3277 return createCXString("NoDeclFound");
3278 case CXCursor_NotImplemented:
3279 return createCXString("NotImplemented");
3280 case CXCursor_TranslationUnit:
3281 return createCXString("TranslationUnit");
Ted Kremenekbff31432010-02-18 03:09:07 +00003282 case CXCursor_UnexposedAttr:
3283 return createCXString("UnexposedAttr");
3284 case CXCursor_IBActionAttr:
3285 return createCXString("attribute(ibaction)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003286 case CXCursor_IBOutletAttr:
3287 return createCXString("attribute(iboutlet)");
Ted Kremenek26bde772010-05-19 17:38:06 +00003288 case CXCursor_IBOutletCollectionAttr:
3289 return createCXString("attribute(iboutletcollection)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003290 case CXCursor_PreprocessingDirective:
3291 return createCXString("preprocessing directive");
Douglas Gregor06d6d322010-03-18 18:04:21 +00003292 case CXCursor_MacroDefinition:
3293 return createCXString("macro definition");
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003294 case CXCursor_MacroInstantiation:
3295 return createCXString("macro instantiation");
Douglas Gregor796d76a2010-10-20 22:00:55 +00003296 case CXCursor_InclusionDirective:
3297 return createCXString("inclusion directive");
Ted Kremenekbd67fb22010-05-06 23:38:21 +00003298 case CXCursor_Namespace:
3299 return createCXString("Namespace");
Ted Kremenekb80cba52010-05-07 01:04:29 +00003300 case CXCursor_LinkageSpec:
3301 return createCXString("LinkageSpec");
Ted Kremenekae9e2212010-08-27 21:34:58 +00003302 case CXCursor_CXXBaseSpecifier:
3303 return createCXString("C++ base class specifier");
Douglas Gregor12bca222010-08-31 14:41:23 +00003304 case CXCursor_Constructor:
3305 return createCXString("CXXConstructor");
3306 case CXCursor_Destructor:
3307 return createCXString("CXXDestructor");
3308 case CXCursor_ConversionFunction:
3309 return createCXString("CXXConversion");
Douglas Gregor713602b2010-08-31 17:01:39 +00003310 case CXCursor_TemplateTypeParameter:
3311 return createCXString("TemplateTypeParameter");
3312 case CXCursor_NonTypeTemplateParameter:
3313 return createCXString("NonTypeTemplateParameter");
3314 case CXCursor_TemplateTemplateParameter:
3315 return createCXString("TemplateTemplateParameter");
3316 case CXCursor_FunctionTemplate:
3317 return createCXString("FunctionTemplate");
Douglas Gregor1fbaeb12010-08-31 19:02:00 +00003318 case CXCursor_ClassTemplate:
3319 return createCXString("ClassTemplate");
Douglas Gregorf96abb22010-08-31 19:31:58 +00003320 case CXCursor_ClassTemplatePartialSpecialization:
3321 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregora89314e2010-08-31 23:48:11 +00003322 case CXCursor_NamespaceAlias:
3323 return createCXString("NamespaceAlias");
Douglas Gregor01a430132010-09-01 03:07:18 +00003324 case CXCursor_UsingDirective:
3325 return createCXString("UsingDirective");
Douglas Gregora9aa29c2010-09-01 19:52:22 +00003326 case CXCursor_UsingDeclaration:
3327 return createCXString("UsingDeclaration");
Steve Naroff1054e602009-08-31 00:59:03 +00003328 }
Ted Kremenek29004672010-02-17 00:41:32 +00003329
Ted Kremenek4ba52632010-01-16 02:02:09 +00003330 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremenek91554282010-11-16 08:15:36 +00003331 return createCXString((const char*) 0);
Steve Naroffd5e8e862009-08-27 19:51:58 +00003332}
Steve Naroff1054e602009-08-31 00:59:03 +00003333
Ted Kremenek29004672010-02-17 00:41:32 +00003334enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3335 CXCursor parent,
Douglas Gregor562c1f92010-01-22 19:49:59 +00003336 CXClientData client_data) {
3337 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor16443fd2010-11-05 21:11:19 +00003338
3339 // If our current best cursor is the construction of a temporary object,
3340 // don't replace that cursor with a type reference, because we want
3341 // clang_getCursor() to point at the constructor.
3342 if (clang_isExpression(BestCursor->kind) &&
3343 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3344 cursor.kind == CXCursor_TypeRef)
3345 return CXChildVisit_Recurse;
3346
Douglas Gregor3046b4d2010-12-10 07:23:11 +00003347 // Don't override a preprocessing cursor with another preprocessing
3348 // cursor; we want the outermost preprocessing cursor.
3349 if (clang_isPreprocessing(cursor.kind) &&
3350 clang_isPreprocessing(BestCursor->kind))
3351 return CXChildVisit_Recurse;
3352
Douglas Gregor562c1f92010-01-22 19:49:59 +00003353 *BestCursor = cursor;
3354 return CXChildVisit_Recurse;
3355}
Ted Kremenek29004672010-02-17 00:41:32 +00003356
Douglas Gregor816fd362010-01-22 21:44:22 +00003357CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3358 if (!TU)
Ted Kremeneke34cbde2010-01-14 01:51:23 +00003359 return clang_getNullCursor();
Ted Kremenek29004672010-02-17 00:41:32 +00003360
Ted Kremenek91554282010-11-16 08:15:36 +00003361 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00003362 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3363
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003364 // Translate the given source location to make it point at the beginning of
3365 // the token under the cursor.
Ted Kremenek97a45372010-01-25 22:34:44 +00003366 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremenek1e589f22010-07-29 00:52:07 +00003367
3368 // Guard against an invalid SourceLocation, or we may assert in one
3369 // of the following calls.
3370 if (SLoc.isInvalid())
3371 return clang_getNullCursor();
3372
Douglas Gregor15417cf2010-11-03 00:35:38 +00003373 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003374 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3375 CXXUnit->getASTContext().getLangOptions());
3376
Douglas Gregor562c1f92010-01-22 19:49:59 +00003377 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3378 if (SLoc.isValid()) {
Douglas Gregor562c1f92010-01-22 19:49:59 +00003379 // FIXME: Would be great to have a "hint" cursor, then walk from that
3380 // hint cursor upward until we find a cursor whose source range encloses
3381 // the region of interest, rather than starting from the translation unit.
Ted Kremenek91554282010-11-16 08:15:36 +00003382 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3383 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregorc2b97992011-03-16 23:23:30 +00003384 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor562c1f92010-01-22 19:49:59 +00003385 CursorVis.VisitChildren(Parent);
Steve Naroff54f22fb2009-09-15 20:25:34 +00003386 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003387
3388 if (Logging) {
3389 CXFile SearchFile;
3390 unsigned SearchLine, SearchColumn;
3391 CXFile ResultFile;
3392 unsigned ResultLine, ResultColumn;
Douglas Gregor29ee4222010-11-17 17:14:07 +00003393 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3394 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor15417cf2010-11-03 00:35:38 +00003395 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3396
3397 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3398 0);
3399 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3400 &ResultColumn, 0);
3401 SearchFileName = clang_getFileName(SearchFile);
3402 ResultFileName = clang_getFileName(ResultFile);
3403 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003404 USR = clang_getCursorUSR(Result);
3405 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor15417cf2010-11-03 00:35:38 +00003406 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3407 clang_getCString(KindSpelling),
Douglas Gregor29ee4222010-11-17 17:14:07 +00003408 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3409 clang_getCString(USR), IsDef);
Douglas Gregor15417cf2010-11-03 00:35:38 +00003410 clang_disposeString(SearchFileName);
3411 clang_disposeString(ResultFileName);
3412 clang_disposeString(KindSpelling);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003413 clang_disposeString(USR);
Douglas Gregor4a5bd5f2010-12-10 01:45:00 +00003414
3415 CXCursor Definition = clang_getCursorDefinition(Result);
3416 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3417 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3418 CXString DefinitionKindSpelling
3419 = clang_getCursorKindSpelling(Definition.kind);
3420 CXFile DefinitionFile;
3421 unsigned DefinitionLine, DefinitionColumn;
3422 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3423 &DefinitionLine, &DefinitionColumn, 0);
3424 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3425 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3426 clang_getCString(DefinitionKindSpelling),
3427 clang_getCString(DefinitionFileName),
3428 DefinitionLine, DefinitionColumn);
3429 clang_disposeString(DefinitionFileName);
3430 clang_disposeString(DefinitionKindSpelling);
3431 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003432 }
3433
Ted Kremenek29004672010-02-17 00:41:32 +00003434 return Result;
Steve Naroffd5e8e862009-08-27 19:51:58 +00003435}
3436
Ted Kremeneke05d7802009-11-17 19:28:59 +00003437CXCursor clang_getNullCursor(void) {
Douglas Gregor58552bc2010-01-20 23:34:41 +00003438 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremeneke05d7802009-11-17 19:28:59 +00003439}
3440
3441unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00003442 return X == Y;
Ted Kremeneke05d7802009-11-17 19:28:59 +00003443}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00003444
Douglas Gregor06a3f302010-11-20 00:09:34 +00003445unsigned clang_hashCursor(CXCursor C) {
3446 unsigned Index = 0;
3447 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3448 Index = 1;
3449
3450 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3451 std::make_pair(C.kind, C.data[Index]));
3452}
3453
Daniel Dunbar079203f2009-12-01 03:14:51 +00003454unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff54f22fb2009-09-15 20:25:34 +00003455 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3456}
3457
Daniel Dunbar079203f2009-12-01 03:14:51 +00003458unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff1054e602009-08-31 00:59:03 +00003459 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3460}
Steve Naroff772c1a42009-08-31 14:26:51 +00003461
Daniel Dunbar079203f2009-12-01 03:14:51 +00003462unsigned clang_isReference(enum CXCursorKind K) {
Steve Naroff80a766b2009-09-02 18:26:48 +00003463 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3464}
3465
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003466unsigned clang_isExpression(enum CXCursorKind K) {
3467 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3468}
3469
3470unsigned clang_isStatement(enum CXCursorKind K) {
3471 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3472}
3473
Douglas Gregord2fc7272010-01-20 00:23:15 +00003474unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3475 return K == CXCursor_TranslationUnit;
3476}
3477
Douglas Gregor92a524f2010-03-18 00:42:48 +00003478unsigned clang_isPreprocessing(enum CXCursorKind K) {
3479 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3480}
3481
Ted Kremenekff9021b2010-03-08 21:17:29 +00003482unsigned clang_isUnexposed(enum CXCursorKind K) {
3483 switch (K) {
3484 case CXCursor_UnexposedDecl:
3485 case CXCursor_UnexposedExpr:
3486 case CXCursor_UnexposedStmt:
3487 case CXCursor_UnexposedAttr:
3488 return true;
3489 default:
3490 return false;
3491 }
3492}
3493
Daniel Dunbar079203f2009-12-01 03:14:51 +00003494CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroffef9618b2009-09-04 15:44:05 +00003495 return C.kind;
3496}
3497
Douglas Gregor66a58812010-01-18 22:46:11 +00003498CXSourceLocation clang_getCursorLocation(CXCursor C) {
3499 if (clang_isReference(C.kind)) {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003500 switch (C.kind) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00003501 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003502 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3503 = getCursorObjCSuperClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003504 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003505 }
3506
Ted Kremenekf441baf2010-02-17 00:41:40 +00003507 case CXCursor_ObjCProtocolRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003508 std::pair<ObjCProtocolDecl *, SourceLocation> P
3509 = getCursorObjCProtocolRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003510 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003511 }
3512
Ted Kremenekf441baf2010-02-17 00:41:40 +00003513 case CXCursor_ObjCClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003514 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3515 = getCursorObjCClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003516 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003517 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003518
Ted Kremenekf441baf2010-02-17 00:41:40 +00003519 case CXCursor_TypeRef: {
Douglas Gregor93f89952010-01-21 16:28:34 +00003520 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003521 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor93f89952010-01-21 16:28:34 +00003522 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00003523
3524 case CXCursor_TemplateRef: {
3525 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3526 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3527 }
3528
Douglas Gregora89314e2010-08-31 23:48:11 +00003529 case CXCursor_NamespaceRef: {
3530 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3531 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3532 }
3533
Douglas Gregorf3af3112010-09-09 21:42:20 +00003534 case CXCursor_MemberRef: {
3535 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3536 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3537 }
3538
Ted Kremenekae9e2212010-08-27 21:34:58 +00003539 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor3478c752010-10-02 19:51:13 +00003540 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3541 if (!BaseSpec)
3542 return clang_getNullLocation();
3543
3544 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3545 return cxloc::translateSourceLocation(getCursorContext(C),
3546 TSInfo->getTypeLoc().getBeginLoc());
3547
3548 return cxloc::translateSourceLocation(getCursorContext(C),
3549 BaseSpec->getSourceRange().getBegin());
Ted Kremenekae9e2212010-08-27 21:34:58 +00003550 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003551
Douglas Gregora93ab662010-09-10 00:22:18 +00003552 case CXCursor_LabelRef: {
3553 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3554 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3555 }
3556
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003557 case CXCursor_OverloadedDeclRef:
3558 return cxloc::translateSourceLocation(getCursorContext(C),
3559 getCursorOverloadedDeclRef(C).second);
3560
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003561 default:
3562 // FIXME: Need a way to enumerate all non-reference cases.
3563 llvm_unreachable("Missed a reference kind");
3564 }
Douglas Gregor66a58812010-01-18 22:46:11 +00003565 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003566
3567 if (clang_isExpression(C.kind))
Ted Kremenekf441baf2010-02-17 00:41:40 +00003568 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003569 getLocationFromExpr(getCursorExpr(C)));
3570
Douglas Gregora93ab662010-09-10 00:22:18 +00003571 if (clang_isStatement(C.kind))
3572 return cxloc::translateSourceLocation(getCursorContext(C),
3573 getCursorStmt(C)->getLocStart());
3574
Douglas Gregor92a524f2010-03-18 00:42:48 +00003575 if (C.kind == CXCursor_PreprocessingDirective) {
3576 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3577 return cxloc::translateSourceLocation(getCursorContext(C), L);
3578 }
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003579
3580 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor065f8d12010-03-18 17:52:52 +00003581 SourceLocation L
3582 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003583 return cxloc::translateSourceLocation(getCursorContext(C), L);
3584 }
Douglas Gregor06d6d322010-03-18 18:04:21 +00003585
3586 if (C.kind == CXCursor_MacroDefinition) {
3587 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3588 return cxloc::translateSourceLocation(getCursorContext(C), L);
3589 }
Douglas Gregor796d76a2010-10-20 22:00:55 +00003590
3591 if (C.kind == CXCursor_InclusionDirective) {
3592 SourceLocation L
3593 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3594 return cxloc::translateSourceLocation(getCursorContext(C), L);
3595 }
3596
Ted Kremenek8278a322010-05-12 06:16:13 +00003597 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003598 return clang_getNullLocation();
Douglas Gregor66a58812010-01-18 22:46:11 +00003599
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003600 Decl *D = getCursorDecl(C);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003601 SourceLocation Loc = D->getLocation();
3602 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3603 Loc = Class->getClassLoc();
Ted Kremenek818e5c12010-11-01 23:26:51 +00003604 // FIXME: Multiple variables declared in a single declaration
3605 // currently lack the information needed to correctly determine their
3606 // ranges when accounting for the type-specifier. We use context
3607 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3608 // and if so, whether it is the first decl.
3609 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3610 if (!cxcursor::isFirstInDeclGroup(C))
3611 Loc = VD->getLocation();
3612 }
3613
Douglas Gregor7bf6b8a2010-03-22 15:53:50 +00003614 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor66a58812010-01-18 22:46:11 +00003615}
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003616
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003617} // end extern "C"
3618
3619static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003620 if (clang_isReference(C.kind)) {
3621 switch (C.kind) {
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003622 case CXCursor_ObjCSuperClassRef:
3623 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003624
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003625 case CXCursor_ObjCProtocolRef:
3626 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003627
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003628 case CXCursor_ObjCClassRef:
3629 return getCursorObjCClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003630
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003631 case CXCursor_TypeRef:
3632 return getCursorTypeRef(C).second;
Douglas Gregora23e8f72010-08-31 20:37:03 +00003633
3634 case CXCursor_TemplateRef:
3635 return getCursorTemplateRef(C).second;
3636
Douglas Gregora89314e2010-08-31 23:48:11 +00003637 case CXCursor_NamespaceRef:
3638 return getCursorNamespaceRef(C).second;
Douglas Gregorf3af3112010-09-09 21:42:20 +00003639
3640 case CXCursor_MemberRef:
3641 return getCursorMemberRef(C).second;
3642
Ted Kremenekae9e2212010-08-27 21:34:58 +00003643 case CXCursor_CXXBaseSpecifier:
Douglas Gregor3478c752010-10-02 19:51:13 +00003644 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor93f89952010-01-21 16:28:34 +00003645
Douglas Gregora93ab662010-09-10 00:22:18 +00003646 case CXCursor_LabelRef:
3647 return getCursorLabelRef(C).second;
3648
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003649 case CXCursor_OverloadedDeclRef:
3650 return getCursorOverloadedDeclRef(C).second;
3651
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003652 default:
3653 // FIXME: Need a way to enumerate all non-reference cases.
3654 llvm_unreachable("Missed a reference kind");
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003655 }
3656 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003657
3658 if (clang_isExpression(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003659 return getCursorExpr(C)->getSourceRange();
Douglas Gregor562c1f92010-01-22 19:49:59 +00003660
3661 if (clang_isStatement(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003662 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003663
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003664 if (C.kind == CXCursor_PreprocessingDirective)
3665 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003666
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003667 if (C.kind == CXCursor_MacroInstantiation)
3668 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor06d6d322010-03-18 18:04:21 +00003669
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003670 if (C.kind == CXCursor_MacroDefinition)
3671 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregor796d76a2010-10-20 22:00:55 +00003672
3673 if (C.kind == CXCursor_InclusionDirective)
3674 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3675
Ted Kremenek818e5c12010-11-01 23:26:51 +00003676 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3677 Decl *D = cxcursor::getCursorDecl(C);
3678 SourceRange R = D->getSourceRange();
3679 // FIXME: Multiple variables declared in a single declaration
3680 // currently lack the information needed to correctly determine their
3681 // ranges when accounting for the type-specifier. We use context
3682 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3683 // and if so, whether it is the first decl.
3684 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3685 if (!cxcursor::isFirstInDeclGroup(C))
3686 R.setBegin(VD->getLocation());
3687 }
3688 return R;
3689 }
Douglas Gregor29ee4222010-11-17 17:14:07 +00003690 return SourceRange();
3691}
3692
3693/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3694/// the decl-specifier-seq for declarations.
3695static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3696 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3697 Decl *D = cxcursor::getCursorDecl(C);
3698 SourceRange R = D->getSourceRange();
Douglas Gregor29ee4222010-11-17 17:14:07 +00003699
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00003700 // Adjust the start of the location for declarations preceded by
3701 // declaration specifiers.
3702 SourceLocation StartLoc;
3703 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3704 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3705 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3706 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3707 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3708 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3709 }
3710
3711 if (StartLoc.isValid() && R.getBegin().isValid() &&
3712 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3713 R.setBegin(StartLoc);
3714
3715 // FIXME: Multiple variables declared in a single declaration
3716 // currently lack the information needed to correctly determine their
3717 // ranges when accounting for the type-specifier. We use context
3718 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3719 // and if so, whether it is the first decl.
3720 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3721 if (!cxcursor::isFirstInDeclGroup(C))
3722 R.setBegin(VD->getLocation());
Douglas Gregor29ee4222010-11-17 17:14:07 +00003723 }
3724
3725 return R;
3726 }
3727
3728 return getRawCursorExtent(C);
3729}
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003730
3731extern "C" {
3732
3733CXSourceRange clang_getCursorExtent(CXCursor C) {
3734 SourceRange R = getRawCursorExtent(C);
3735 if (R.isInvalid())
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003736 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003737
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003738 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003739}
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003740
3741CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003742 if (clang_isInvalid(C.kind))
3743 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003744
Ted Kremenek91554282010-11-16 08:15:36 +00003745 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003746 if (clang_isDeclaration(C.kind)) {
3747 Decl *D = getCursorDecl(C);
3748 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003749 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003750 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003751 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003752 if (ObjCForwardProtocolDecl *Protocols
3753 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003754 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00003755 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3756 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3757 return MakeCXCursor(Property, tu);
3758
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003759 return C;
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003760 }
3761
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003762 if (clang_isExpression(C.kind)) {
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003763 Expr *E = getCursorExpr(C);
3764 Decl *D = getDeclFromExpr(E);
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003765 if (D)
Ted Kremenek91554282010-11-16 08:15:36 +00003766 return MakeCXCursor(D, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003767
3768 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremenek91554282010-11-16 08:15:36 +00003769 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003770
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003771 return clang_getNullCursor();
3772 }
3773
Douglas Gregora93ab662010-09-10 00:22:18 +00003774 if (clang_isStatement(C.kind)) {
3775 Stmt *S = getCursorStmt(C);
3776 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek6f7008d2011-03-15 23:47:49 +00003777 if (LabelDecl *label = Goto->getLabel())
3778 if (LabelStmt *labelS = label->getStmt())
3779 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003780
3781 return clang_getNullCursor();
3782 }
3783
Douglas Gregor78ae2482010-03-18 18:23:03 +00003784 if (C.kind == CXCursor_MacroInstantiation) {
3785 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003786 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregor78ae2482010-03-18 18:23:03 +00003787 }
3788
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003789 if (!clang_isReference(C.kind))
3790 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003791
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003792 switch (C.kind) {
3793 case CXCursor_ObjCSuperClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003794 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003795
3796 case CXCursor_ObjCProtocolRef: {
Ted Kremenek91554282010-11-16 08:15:36 +00003797 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003798
3799 case CXCursor_ObjCClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003800 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor93f89952010-01-21 16:28:34 +00003801
Ted Kremenekf441baf2010-02-17 00:41:40 +00003802 case CXCursor_TypeRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003803 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003804
3805 case CXCursor_TemplateRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003806 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003807
Douglas Gregora89314e2010-08-31 23:48:11 +00003808 case CXCursor_NamespaceRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003809 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregora89314e2010-08-31 23:48:11 +00003810
Douglas Gregorf3af3112010-09-09 21:42:20 +00003811 case CXCursor_MemberRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003812 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregorf3af3112010-09-09 21:42:20 +00003813
Ted Kremenekae9e2212010-08-27 21:34:58 +00003814 case CXCursor_CXXBaseSpecifier: {
3815 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3816 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremenek91554282010-11-16 08:15:36 +00003817 tu ));
Ted Kremenekae9e2212010-08-27 21:34:58 +00003818 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003819
Douglas Gregora93ab662010-09-10 00:22:18 +00003820 case CXCursor_LabelRef:
3821 // FIXME: We end up faking the "parent" declaration here because we
3822 // don't want to make CXCursor larger.
3823 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremenek91554282010-11-16 08:15:36 +00003824 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3825 .getTranslationUnitDecl(),
3826 tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003827
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003828 case CXCursor_OverloadedDeclRef:
3829 return C;
3830
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003831 default:
3832 // We would prefer to enumerate all non-reference cursor kinds here.
3833 llvm_unreachable("Unhandled reference cursor kind");
3834 break;
3835 }
3836 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003837
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003838 return clang_getNullCursor();
3839}
3840
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003841CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003842 if (clang_isInvalid(C.kind))
3843 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003844
Ted Kremenek91554282010-11-16 08:15:36 +00003845 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003846
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003847 bool WasReference = false;
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003848 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003849 C = clang_getCursorReferenced(C);
3850 WasReference = true;
3851 }
3852
Douglas Gregor78ae2482010-03-18 18:23:03 +00003853 if (C.kind == CXCursor_MacroInstantiation)
3854 return clang_getCursorReferenced(C);
3855
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003856 if (!clang_isDeclaration(C.kind))
3857 return clang_getNullCursor();
3858
3859 Decl *D = getCursorDecl(C);
3860 if (!D)
3861 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003862
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003863 switch (D->getKind()) {
3864 // Declaration kinds that don't really separate the notions of
3865 // declaration and definition.
3866 case Decl::Namespace:
3867 case Decl::Typedef:
3868 case Decl::TemplateTypeParm:
3869 case Decl::EnumConstant:
3870 case Decl::Field:
Benjamin Kramer39593702010-11-21 14:11:41 +00003871 case Decl::IndirectField:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003872 case Decl::ObjCIvar:
3873 case Decl::ObjCAtDefsField:
3874 case Decl::ImplicitParam:
3875 case Decl::ParmVar:
3876 case Decl::NonTypeTemplateParm:
3877 case Decl::TemplateTemplateParm:
3878 case Decl::ObjCCategoryImpl:
3879 case Decl::ObjCImplementation:
Abramo Bagnarad7340582010-06-05 05:09:32 +00003880 case Decl::AccessSpec:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003881 case Decl::LinkageSpec:
3882 case Decl::ObjCPropertyImpl:
3883 case Decl::FileScopeAsm:
3884 case Decl::StaticAssert:
3885 case Decl::Block:
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003886 case Decl::Label: // FIXME: Is this right??
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003887 return C;
3888
3889 // Declaration kinds that don't make any sense here, but are
3890 // nonetheless harmless.
3891 case Decl::TranslationUnit:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003892 break;
3893
3894 // Declaration kinds for which the definition is not resolvable.
3895 case Decl::UnresolvedUsingTypename:
3896 case Decl::UnresolvedUsingValue:
3897 break;
3898
3899 case Decl::UsingDirective:
Douglas Gregorfed36b12010-01-20 23:57:43 +00003900 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremenek91554282010-11-16 08:15:36 +00003901 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003902
3903 case Decl::NamespaceAlias:
Ted Kremenek91554282010-11-16 08:15:36 +00003904 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003905
3906 case Decl::Enum:
3907 case Decl::Record:
3908 case Decl::CXXRecord:
3909 case Decl::ClassTemplateSpecialization:
3910 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003911 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003912 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003913 return clang_getNullCursor();
3914
3915 case Decl::Function:
3916 case Decl::CXXMethod:
3917 case Decl::CXXConstructor:
3918 case Decl::CXXDestructor:
3919 case Decl::CXXConversion: {
3920 const FunctionDecl *Def = 0;
3921 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003922 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003923 return clang_getNullCursor();
3924 }
3925
3926 case Decl::Var: {
Sebastian Redl5ca79842010-02-01 20:16:42 +00003927 // Ask the variable if it has a definition.
3928 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003929 return MakeCXCursor(Def, TU);
Sebastian Redl5ca79842010-02-01 20:16:42 +00003930 return clang_getNullCursor();
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003931 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003932
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003933 case Decl::FunctionTemplate: {
3934 const FunctionDecl *Def = 0;
3935 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003936 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003937 return clang_getNullCursor();
3938 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003939
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003940 case Decl::ClassTemplate: {
3941 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003942 ->getDefinition())
Douglas Gregora23e8f72010-08-31 20:37:03 +00003943 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremenek91554282010-11-16 08:15:36 +00003944 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003945 return clang_getNullCursor();
3946 }
3947
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003948 case Decl::Using:
3949 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00003950 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003951
3952 case Decl::UsingShadow:
3953 return clang_getCursorDefinition(
Ted Kremenekf441baf2010-02-17 00:41:40 +00003954 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremenek91554282010-11-16 08:15:36 +00003955 TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003956
3957 case Decl::ObjCMethod: {
3958 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3959 if (Method->isThisDeclarationADefinition())
3960 return C;
3961
3962 // Dig out the method definition in the associated
3963 // @implementation, if we have it.
3964 // FIXME: The ASTs should make finding the definition easier.
3965 if (ObjCInterfaceDecl *Class
3966 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3967 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3968 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3969 Method->isInstanceMethod()))
3970 if (Def->isThisDeclarationADefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003971 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003972
3973 return clang_getNullCursor();
3974 }
3975
3976 case Decl::ObjCCategory:
3977 if (ObjCCategoryImplDecl *Impl
3978 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00003979 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003980 return clang_getNullCursor();
3981
3982 case Decl::ObjCProtocol:
3983 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3984 return C;
3985 return clang_getNullCursor();
3986
3987 case Decl::ObjCInterface:
3988 // There are two notions of a "definition" for an Objective-C
3989 // class: the interface and its implementation. When we resolved a
3990 // reference to an Objective-C class, produce the @interface as
3991 // the definition; when we were provided with the interface,
3992 // produce the @implementation as the definition.
3993 if (WasReference) {
3994 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
3995 return C;
3996 } else if (ObjCImplementationDecl *Impl
3997 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00003998 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003999 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004000
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004001 case Decl::ObjCProperty:
4002 // FIXME: We don't really know where to find the
4003 // ObjCPropertyImplDecls that implement this property.
4004 return clang_getNullCursor();
4005
4006 case Decl::ObjCCompatibleAlias:
4007 if (ObjCInterfaceDecl *Class
4008 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4009 if (!Class->isForwardDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004010 return MakeCXCursor(Class, TU);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004011
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004012 return clang_getNullCursor();
4013
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004014 case Decl::ObjCForwardProtocol:
4015 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00004016 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004017
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004018 case Decl::ObjCClass:
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00004019 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremenek91554282010-11-16 08:15:36 +00004020 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004021
4022 case Decl::Friend:
4023 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004024 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004025 return clang_getNullCursor();
4026
4027 case Decl::FriendTemplate:
4028 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004029 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004030 return clang_getNullCursor();
4031 }
4032
4033 return clang_getNullCursor();
4034}
4035
4036unsigned clang_isCursorDefinition(CXCursor C) {
4037 if (!clang_isDeclaration(C.kind))
4038 return 0;
4039
4040 return clang_getCursorDefinition(C) == C;
4041}
4042
Douglas Gregorfec4dc92010-11-19 23:44:15 +00004043CXCursor clang_getCanonicalCursor(CXCursor C) {
4044 if (!clang_isDeclaration(C.kind))
4045 return C;
4046
4047 if (Decl *D = getCursorDecl(C))
4048 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4049
4050 return C;
4051}
4052
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004053unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregorae185302010-09-16 13:54:00 +00004054 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004055 return 0;
4056
4057 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4058 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4059 return E->getNumDecls();
4060
4061 if (OverloadedTemplateStorage *S
4062 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4063 return S->size();
4064
4065 Decl *D = Storage.get<Decl*>();
4066 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis2703beb2010-11-10 05:40:41 +00004067 return Using->shadow_size();
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004068 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4069 return Classes->size();
4070 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4071 return Protocols->protocol_size();
4072
4073 return 0;
4074}
4075
4076CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregorae185302010-09-16 13:54:00 +00004077 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004078 return clang_getNullCursor();
4079
4080 if (index >= clang_getNumOverloadedDecls(cursor))
4081 return clang_getNullCursor();
4082
Ted Kremenek91554282010-11-16 08:15:36 +00004083 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004084 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4085 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremenek91554282010-11-16 08:15:36 +00004086 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004087
4088 if (OverloadedTemplateStorage *S
4089 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremenek91554282010-11-16 08:15:36 +00004090 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004091
4092 Decl *D = Storage.get<Decl*>();
4093 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4094 // FIXME: This is, unfortunately, linear time.
4095 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4096 std::advance(Pos, index);
Ted Kremenek91554282010-11-16 08:15:36 +00004097 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004098 }
4099
4100 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004101 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004102
4103 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004104 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004105
4106 return clang_getNullCursor();
4107}
4108
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00004109void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff76b8f132009-09-23 17:52:52 +00004110 const char **startBuf,
4111 const char **endBuf,
4112 unsigned *startLine,
4113 unsigned *startColumn,
4114 unsigned *endLine,
Daniel Dunbar079203f2009-12-01 03:14:51 +00004115 unsigned *endColumn) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00004116 assert(getCursorDecl(C) && "CXCursor has null decl");
4117 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff76b8f132009-09-23 17:52:52 +00004118 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4119 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004120
Steve Naroff76b8f132009-09-23 17:52:52 +00004121 SourceManager &SM = FD->getASTContext().getSourceManager();
4122 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4123 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4124 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4125 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4126 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4127 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4128}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004129
Douglas Gregor1e21cc72010-02-18 23:07:20 +00004130void clang_enableStackTraces(void) {
4131 llvm::sys::PrintStackTraceOnErrorSignal();
4132}
4133
Daniel Dunbar23420652010-11-04 01:26:29 +00004134void clang_executeOnThread(void (*fn)(void*), void *user_data,
4135 unsigned stack_size) {
4136 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4137}
4138
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004139} // end: extern "C"
Steve Naroff76b8f132009-09-23 17:52:52 +00004140
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004141//===----------------------------------------------------------------------===//
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004142// Token-based Operations.
4143//===----------------------------------------------------------------------===//
4144
4145/* CXToken layout:
4146 * int_data[0]: a CXTokenKind
4147 * int_data[1]: starting token location
4148 * int_data[2]: token length
4149 * int_data[3]: reserved
Ted Kremenekf441baf2010-02-17 00:41:40 +00004150 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004151 * otherwise unused.
4152 */
4153extern "C" {
4154
4155CXTokenKind clang_getTokenKind(CXToken CXTok) {
4156 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4157}
4158
4159CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4160 switch (clang_getTokenKind(CXTok)) {
4161 case CXToken_Identifier:
4162 case CXToken_Keyword:
4163 // We know we have an IdentifierInfo*, so use that.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004164 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4165 ->getNameStart());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004166
4167 case CXToken_Literal: {
4168 // We have stashed the starting pointer in the ptr_data field. Use it.
4169 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004170 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004171 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004172
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004173 case CXToken_Punctuation:
4174 case CXToken_Comment:
4175 break;
4176 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004177
4178 // We have to find the starting buffer pointer the hard way, by
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004179 // deconstructing the source location.
Ted Kremenek91554282010-11-16 08:15:36 +00004180 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004181 if (!CXXUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004182 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00004183
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004184 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4185 std::pair<FileID, unsigned> LocInfo
4186 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregore0fbb832010-03-16 00:06:06 +00004187 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004188 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004189 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4190 if (Invalid)
Douglas Gregor802b7762010-03-15 22:54:52 +00004191 return createCXString("");
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004192
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004193 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004194}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004195
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004196CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004197 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004198 if (!CXXUnit)
4199 return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004200
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004201 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4202 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4203}
4204
4205CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004206 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4f9c3762010-01-28 00:27:43 +00004207 if (!CXXUnit)
4208 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004209
4210 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004211 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4212}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004213
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004214void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4215 CXToken **Tokens, unsigned *NumTokens) {
4216 if (Tokens)
4217 *Tokens = 0;
4218 if (NumTokens)
4219 *NumTokens = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004220
Ted Kremenek91554282010-11-16 08:15:36 +00004221 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004222 if (!CXXUnit || !Tokens || !NumTokens)
4223 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004224
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004225 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4226
Daniel Dunbar80daf532010-02-14 08:31:57 +00004227 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004228 if (R.isInvalid())
4229 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004230
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004231 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4232 std::pair<FileID, unsigned> BeginLocInfo
4233 = SourceMgr.getDecomposedLoc(R.getBegin());
4234 std::pair<FileID, unsigned> EndLocInfo
4235 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004236
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004237 // Cannot tokenize across files.
4238 if (BeginLocInfo.first != EndLocInfo.first)
4239 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004240
4241 // Create a lexer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004242 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004243 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004244 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor554e0b12010-03-16 20:26:15 +00004245 if (Invalid)
4246 return;
Douglas Gregor802b7762010-03-15 22:54:52 +00004247
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004248 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4249 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004250 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004251 Lex.SetCommentRetentionState(true);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004252
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004253 // Lex tokens until we hit the end of the range.
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004254 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004255 llvm::SmallVector<CXToken, 32> CXTokens;
4256 Token Tok;
David Chisnall1822d1f2010-10-13 21:44:48 +00004257 bool previousWasAt = false;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004258 do {
4259 // Lex the next token
4260 Lex.LexFromRawLexer(Tok);
4261 if (Tok.is(tok::eof))
4262 break;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004263
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004264 // Initialize the CXToken.
4265 CXToken CXTok;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004266
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004267 // - Common fields
4268 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4269 CXTok.int_data[2] = Tok.getLength();
4270 CXTok.int_data[3] = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004271
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004272 // - Kind-specific fields
4273 if (Tok.isLiteral()) {
4274 CXTok.int_data[0] = CXToken_Literal;
4275 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004276 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregor802b7762010-03-15 22:54:52 +00004277 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004278 IdentifierInfo *II
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004279 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004280
David Chisnall1822d1f2010-10-13 21:44:48 +00004281 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004282 CXTok.int_data[0] = CXToken_Keyword;
4283 }
4284 else {
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004285 CXTok.int_data[0] = Tok.is(tok::identifier)
4286 ? CXToken_Identifier
4287 : CXToken_Keyword;
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004288 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004289 CXTok.ptr_data = II;
4290 } else if (Tok.is(tok::comment)) {
4291 CXTok.int_data[0] = CXToken_Comment;
4292 CXTok.ptr_data = 0;
4293 } else {
4294 CXTok.int_data[0] = CXToken_Punctuation;
4295 CXTok.ptr_data = 0;
4296 }
4297 CXTokens.push_back(CXTok);
David Chisnall1822d1f2010-10-13 21:44:48 +00004298 previousWasAt = Tok.is(tok::at);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004299 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004300
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004301 if (CXTokens.empty())
4302 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004303
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004304 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4305 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4306 *NumTokens = CXTokens.size();
4307}
Douglas Gregor61656112010-01-26 18:31:56 +00004308
Ted Kremenek63ac5992010-05-05 00:55:15 +00004309void clang_disposeTokens(CXTranslationUnit TU,
4310 CXToken *Tokens, unsigned NumTokens) {
4311 free(Tokens);
4312}
4313
4314} // end: extern "C"
4315
4316//===----------------------------------------------------------------------===//
4317// Token annotation APIs.
4318//===----------------------------------------------------------------------===//
4319
Douglas Gregor61656112010-01-26 18:31:56 +00004320typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenek680fe512010-05-05 00:55:23 +00004321static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4322 CXCursor parent,
4323 CXClientData client_data);
Ted Kremenek63ac5992010-05-05 00:55:15 +00004324namespace {
4325class AnnotateTokensWorker {
4326 AnnotateTokensData &Annotated;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004327 CXToken *Tokens;
4328 CXCursor *Cursors;
4329 unsigned NumTokens;
Ted Kremenek680fe512010-05-05 00:55:23 +00004330 unsigned TokIdx;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004331 unsigned PreprocessingTokIdx;
Ted Kremenek680fe512010-05-05 00:55:23 +00004332 CursorVisitor AnnotateVis;
4333 SourceManager &SrcMgr;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004334 bool HasContextSensitiveKeywords;
4335
Ted Kremenek680fe512010-05-05 00:55:23 +00004336 bool MoreTokens() const { return TokIdx < NumTokens; }
4337 unsigned NextToken() const { return TokIdx; }
4338 void AdvanceToken() { ++TokIdx; }
4339 SourceLocation GetTokenLoc(unsigned tokI) {
4340 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4341 }
4342
Ted Kremenek63ac5992010-05-05 00:55:15 +00004343public:
Ted Kremenek458c2f12010-05-05 00:55:17 +00004344 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenek680fe512010-05-05 00:55:23 +00004345 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremenek91554282010-11-16 08:15:36 +00004346 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek458c2f12010-05-05 00:55:17 +00004347 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004348 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremenek91554282010-11-16 08:15:36 +00004349 AnnotateVis(tu,
4350 AnnotateTokensVisitor, this,
Douglas Gregorc2b97992011-03-16 23:23:30 +00004351 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf2f08062011-03-08 17:10:18 +00004352 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4353 HasContextSensitiveKeywords(false) { }
Ted Kremenek458c2f12010-05-05 00:55:17 +00004354
Ted Kremenek680fe512010-05-05 00:55:23 +00004355 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004356 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenek680fe512010-05-05 00:55:23 +00004357 void AnnotateTokens(CXCursor parent);
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004358 void AnnotateTokens() {
Ted Kremenek91554282010-11-16 08:15:36 +00004359 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004360 }
Douglas Gregorf2f08062011-03-08 17:10:18 +00004361
4362 /// \brief Determine whether the annotator saw any cursors that have
4363 /// context-sensitive keywords.
4364 bool hasContextSensitiveKeywords() const {
4365 return HasContextSensitiveKeywords;
4366 }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004367};
4368}
Douglas Gregor61656112010-01-26 18:31:56 +00004369
Ted Kremenek680fe512010-05-05 00:55:23 +00004370void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4371 // Walk the AST within the region of interest, annotating tokens
4372 // along the way.
4373 VisitChildren(parent);
Ted Kremenek458c2f12010-05-05 00:55:17 +00004374
Ted Kremenek680fe512010-05-05 00:55:23 +00004375 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4376 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004377 if (Pos != Annotated.end() &&
4378 (clang_isInvalid(Cursors[I].kind) ||
4379 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenek680fe512010-05-05 00:55:23 +00004380 Cursors[I] = Pos->second;
4381 }
4382
4383 // Finish up annotating any tokens left.
4384 if (!MoreTokens())
4385 return;
4386
4387 const CXCursor &C = clang_getNullCursor();
4388 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4389 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4390 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004391 }
4392}
4393
Ted Kremenek63ac5992010-05-05 00:55:15 +00004394enum CXChildVisitResult
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004395AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004396 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004397 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004398 if (cursorRange.isInvalid())
4399 return CXChildVisit_Recurse;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004400
4401 if (!HasContextSensitiveKeywords) {
4402 // Objective-C properties can have context-sensitive keywords.
4403 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4404 if (ObjCPropertyDecl *Property
4405 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4406 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4407 }
4408 // Objective-C methods can have context-sensitive keywords.
4409 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4410 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4411 if (ObjCMethodDecl *Method
4412 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4413 if (Method->getObjCDeclQualifier())
4414 HasContextSensitiveKeywords = true;
4415 else {
4416 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4417 PEnd = Method->param_end();
4418 P != PEnd; ++P) {
4419 if ((*P)->getObjCDeclQualifier()) {
4420 HasContextSensitiveKeywords = true;
4421 break;
4422 }
4423 }
4424 }
4425 }
4426 }
4427 // C++ methods can have context-sensitive keywords.
4428 else if (cursor.kind == CXCursor_CXXMethod) {
4429 if (CXXMethodDecl *Method
4430 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4431 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4432 HasContextSensitiveKeywords = true;
4433 }
4434 }
4435 // C++ classes can have context-sensitive keywords.
4436 else if (cursor.kind == CXCursor_StructDecl ||
4437 cursor.kind == CXCursor_ClassDecl ||
4438 cursor.kind == CXCursor_ClassTemplate ||
4439 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4440 if (Decl *D = getCursorDecl(cursor))
4441 if (D->hasAttr<FinalAttr>())
4442 HasContextSensitiveKeywords = true;
4443 }
4444 }
4445
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004446 if (clang_isPreprocessing(cursor.kind)) {
4447 // For macro instantiations, just note where the beginning of the macro
4448 // instantiation occurs.
4449 if (cursor.kind == CXCursor_MacroInstantiation) {
4450 Annotated[Loc.int_data] = cursor;
4451 return CXChildVisit_Recurse;
4452 }
4453
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004454 // Items in the preprocessing record are kept separate from items in
4455 // declarations, so we keep a separate token index.
4456 unsigned SavedTokIdx = TokIdx;
4457 TokIdx = PreprocessingTokIdx;
4458
4459 // Skip tokens up until we catch up to the beginning of the preprocessing
4460 // entry.
4461 while (MoreTokens()) {
4462 const unsigned I = NextToken();
4463 SourceLocation TokLoc = GetTokenLoc(I);
4464 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4465 case RangeBefore:
4466 AdvanceToken();
4467 continue;
4468 case RangeAfter:
4469 case RangeOverlap:
4470 break;
4471 }
4472 break;
4473 }
4474
4475 // Look at all of the tokens within this range.
4476 while (MoreTokens()) {
4477 const unsigned I = NextToken();
4478 SourceLocation TokLoc = GetTokenLoc(I);
4479 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4480 case RangeBefore:
4481 assert(0 && "Infeasible");
4482 case RangeAfter:
4483 break;
4484 case RangeOverlap:
4485 Cursors[I] = cursor;
4486 AdvanceToken();
4487 continue;
4488 }
4489 break;
4490 }
4491
4492 // Save the preprocessing token index; restore the non-preprocessing
4493 // token index.
4494 PreprocessingTokIdx = TokIdx;
4495 TokIdx = SavedTokIdx;
Douglas Gregor61656112010-01-26 18:31:56 +00004496 return CXChildVisit_Recurse;
4497 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004498
Ted Kremenek680fe512010-05-05 00:55:23 +00004499 if (cursorRange.isInvalid())
4500 return CXChildVisit_Continue;
Ted Kremenek5d616142010-05-12 05:29:33 +00004501
Ted Kremenek680fe512010-05-05 00:55:23 +00004502 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4503
Ted Kremenek5d616142010-05-12 05:29:33 +00004504 // Adjust the annotated range based specific declarations.
4505 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4506 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek49be9e02010-05-18 21:09:07 +00004507 Decl *D = cxcursor::getCursorDecl(cursor);
4508 // Don't visit synthesized ObjC methods, since they have no syntatic
4509 // representation in the source.
4510 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4511 if (MD->isSynthesized())
4512 return CXChildVisit_Continue;
4513 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004514
4515 SourceLocation StartLoc;
Ted Kremenek49be9e02010-05-18 21:09:07 +00004516 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004517 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4518 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4519 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4520 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4521 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremenek5d616142010-05-12 05:29:33 +00004522 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004523
4524 if (StartLoc.isValid() && L.isValid() &&
4525 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4526 cursorRange.setBegin(StartLoc);
Ted Kremenek5d616142010-05-12 05:29:33 +00004527 }
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004528
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004529 // If the location of the cursor occurs within a macro instantiation, record
4530 // the spelling location of the cursor in our annotation map. We can then
4531 // paper over the token labelings during a post-processing step to try and
4532 // get cursor mappings for tokens that are the *arguments* of a macro
4533 // instantiation.
4534 if (L.isMacroID()) {
4535 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4536 // Only invalidate the old annotation if it isn't part of a preprocessing
4537 // directive. Here we assume that the default construction of CXCursor
4538 // results in CXCursor.kind being an initialized value (i.e., 0). If
4539 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004540
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004541 CXCursor &oldC = Annotated[rawEncoding];
4542 if (!clang_isPreprocessing(oldC.kind))
4543 oldC = cursor;
4544 }
4545
Ted Kremenek680fe512010-05-05 00:55:23 +00004546 const enum CXCursorKind K = clang_getCursorKind(parent);
4547 const CXCursor updateC =
Ted Kremenek65b2cc02010-08-25 22:16:02 +00004548 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4549 ? clang_getNullCursor() : parent;
Ted Kremenek680fe512010-05-05 00:55:23 +00004550
4551 while (MoreTokens()) {
4552 const unsigned I = NextToken();
4553 SourceLocation TokLoc = GetTokenLoc(I);
4554 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4555 case RangeBefore:
4556 Cursors[I] = updateC;
4557 AdvanceToken();
4558 continue;
4559 case RangeAfter:
Ted Kremenek680fe512010-05-05 00:55:23 +00004560 case RangeOverlap:
4561 break;
4562 }
4563 break;
4564 }
4565
4566 // Visit children to get their cursor information.
4567 const unsigned BeforeChildren = NextToken();
4568 VisitChildren(cursor);
4569 const unsigned AfterChildren = NextToken();
4570
4571 // Adjust 'Last' to the last token within the extent of the cursor.
4572 while (MoreTokens()) {
4573 const unsigned I = NextToken();
4574 SourceLocation TokLoc = GetTokenLoc(I);
4575 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4576 case RangeBefore:
4577 assert(0 && "Infeasible");
4578 case RangeAfter:
4579 break;
4580 case RangeOverlap:
4581 Cursors[I] = updateC;
4582 AdvanceToken();
4583 continue;
4584 }
4585 break;
4586 }
4587 const unsigned Last = NextToken();
Ted Kremenek63ac5992010-05-05 00:55:15 +00004588
Ted Kremenek680fe512010-05-05 00:55:23 +00004589 // Scan the tokens that are at the beginning of the cursor, but are not
4590 // capture by the child cursors.
4591
4592 // For AST elements within macros, rely on a post-annotate pass to
4593 // to correctly annotate the tokens with cursors. Otherwise we can
4594 // get confusing results of having tokens that map to cursors that really
4595 // are expanded by an instantiation.
4596 if (L.isMacroID())
4597 cursor = clang_getNullCursor();
4598
4599 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4600 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4601 break;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004602
Ted Kremenek680fe512010-05-05 00:55:23 +00004603 Cursors[I] = cursor;
4604 }
4605 // Scan the tokens that are at the end of the cursor, but are not captured
4606 // but the child cursors.
4607 for (unsigned I = AfterChildren; I != Last; ++I)
4608 Cursors[I] = cursor;
4609
4610 TokIdx = Last;
4611 return CXChildVisit_Continue;
Douglas Gregor61656112010-01-26 18:31:56 +00004612}
4613
Ted Kremenek63ac5992010-05-05 00:55:15 +00004614static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4615 CXCursor parent,
4616 CXClientData client_data) {
4617 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4618}
4619
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004620namespace {
4621 struct clang_annotateTokens_Data {
4622 CXTranslationUnit TU;
4623 ASTUnit *CXXUnit;
4624 CXToken *Tokens;
4625 unsigned NumTokens;
4626 CXCursor *Cursors;
4627 };
4628}
4629
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004630// This gets run a separate thread to avoid stack blowout.
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004631static void clang_annotateTokensImpl(void *UserData) {
4632 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4633 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4634 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4635 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4636 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4637
4638 // Determine the region of interest, which contains all of the tokens.
4639 SourceRange RegionOfInterest;
4640 RegionOfInterest.setBegin(
4641 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4642 RegionOfInterest.setEnd(
4643 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4644 Tokens[NumTokens-1])));
4645
4646 // A mapping from the source locations found when re-lexing or traversing the
4647 // region of interest to the corresponding cursors.
4648 AnnotateTokensData Annotated;
4649
4650 // Relex the tokens within the source range to look for preprocessing
4651 // directives.
4652 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4653 std::pair<FileID, unsigned> BeginLocInfo
4654 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4655 std::pair<FileID, unsigned> EndLocInfo
4656 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4657
4658 llvm::StringRef Buffer;
4659 bool Invalid = false;
4660 if (BeginLocInfo.first == EndLocInfo.first &&
4661 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4662 !Invalid) {
4663 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4664 CXXUnit->getASTContext().getLangOptions(),
4665 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4666 Buffer.end());
4667 Lex.SetCommentRetentionState(true);
4668
4669 // Lex tokens in raw mode until we hit the end of the range, to avoid
4670 // entering #includes or expanding macros.
4671 while (true) {
4672 Token Tok;
4673 Lex.LexFromRawLexer(Tok);
4674
4675 reprocess:
4676 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4677 // We have found a preprocessing directive. Gobble it up so that we
4678 // don't see it while preprocessing these tokens later, but keep track
4679 // of all of the token locations inside this preprocessing directive so
4680 // that we can annotate them appropriately.
4681 //
4682 // FIXME: Some simple tests here could identify macro definitions and
4683 // #undefs, to provide specific cursor kinds for those.
4684 llvm::SmallVector<SourceLocation, 32> Locations;
4685 do {
4686 Locations.push_back(Tok.getLocation());
4687 Lex.LexFromRawLexer(Tok);
4688 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4689
4690 using namespace cxcursor;
4691 CXCursor Cursor
4692 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4693 Locations.back()),
4694 TU);
4695 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4696 Annotated[Locations[I].getRawEncoding()] = Cursor;
4697 }
4698
4699 if (Tok.isAtStartOfLine())
4700 goto reprocess;
4701
4702 continue;
4703 }
4704
4705 if (Tok.is(tok::eof))
4706 break;
4707 }
4708 }
4709
4710 // Annotate all of the source locations in the region of interest that map to
4711 // a specific cursor.
4712 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4713 TU, RegionOfInterest);
4714
4715 // FIXME: We use a ridiculous stack size here because the data-recursion
4716 // algorithm uses a large stack frame than the non-data recursive version,
4717 // and AnnotationTokensWorker currently transforms the data-recursion
4718 // algorithm back into a traditional recursion by explicitly calling
4719 // VisitChildren(). We will need to remove this explicit recursive call.
4720 W.AnnotateTokens();
4721
4722 // If we ran into any entities that involve context-sensitive keywords,
4723 // take another pass through the tokens to mark them as such.
4724 if (W.hasContextSensitiveKeywords()) {
4725 for (unsigned I = 0; I != NumTokens; ++I) {
4726 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4727 continue;
4728
4729 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4730 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4731 if (ObjCPropertyDecl *Property
4732 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4733 if (Property->getPropertyAttributesAsWritten() != 0 &&
4734 llvm::StringSwitch<bool>(II->getName())
4735 .Case("readonly", true)
4736 .Case("assign", true)
4737 .Case("readwrite", true)
4738 .Case("retain", true)
4739 .Case("copy", true)
4740 .Case("nonatomic", true)
4741 .Case("atomic", true)
4742 .Case("getter", true)
4743 .Case("setter", true)
4744 .Default(false))
4745 Tokens[I].int_data[0] = CXToken_Keyword;
4746 }
4747 continue;
4748 }
4749
4750 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4751 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4752 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4753 if (llvm::StringSwitch<bool>(II->getName())
4754 .Case("in", true)
4755 .Case("out", true)
4756 .Case("inout", true)
4757 .Case("oneway", true)
4758 .Case("bycopy", true)
4759 .Case("byref", true)
4760 .Default(false))
4761 Tokens[I].int_data[0] = CXToken_Keyword;
4762 continue;
4763 }
4764
4765 if (Cursors[I].kind == CXCursor_CXXMethod) {
4766 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4767 if (CXXMethodDecl *Method
4768 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4769 if ((Method->hasAttr<FinalAttr>() ||
4770 Method->hasAttr<OverrideAttr>()) &&
4771 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4772 llvm::StringSwitch<bool>(II->getName())
4773 .Case("final", true)
4774 .Case("override", true)
4775 .Default(false))
4776 Tokens[I].int_data[0] = CXToken_Keyword;
4777 }
4778 continue;
4779 }
4780
4781 if (Cursors[I].kind == CXCursor_ClassDecl ||
4782 Cursors[I].kind == CXCursor_StructDecl ||
4783 Cursors[I].kind == CXCursor_ClassTemplate) {
4784 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4785 if (II->getName() == "final") {
4786 // We have to be careful with 'final', since it could be the name
4787 // of a member class rather than the context-sensitive keyword.
4788 // So, check whether the cursor associated with this
4789 Decl *D = getCursorDecl(Cursors[I]);
4790 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4791 if ((Record->hasAttr<FinalAttr>()) &&
4792 Record->getIdentifier() != II)
4793 Tokens[I].int_data[0] = CXToken_Keyword;
4794 } else if (ClassTemplateDecl *ClassTemplate
4795 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4796 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4797 if ((Record->hasAttr<FinalAttr>()) &&
4798 Record->getIdentifier() != II)
4799 Tokens[I].int_data[0] = CXToken_Keyword;
4800 }
4801 }
4802 continue;
4803 }
4804 }
4805 }
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004806}
4807
Ted Kremenek63ac5992010-05-05 00:55:15 +00004808extern "C" {
4809
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004810void clang_annotateTokens(CXTranslationUnit TU,
4811 CXToken *Tokens, unsigned NumTokens,
4812 CXCursor *Cursors) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004813
4814 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor61656112010-01-26 18:31:56 +00004815 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004816
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004817 // Any token we don't specifically annotate will have a NULL cursor.
4818 CXCursor C = clang_getNullCursor();
4819 for (unsigned I = 0; I != NumTokens; ++I)
4820 Cursors[I] = C;
4821
Ted Kremenek91554282010-11-16 08:15:36 +00004822 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004823 if (!CXXUnit)
Douglas Gregor61656112010-01-26 18:31:56 +00004824 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004825
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004826 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004827
4828 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004829 llvm::CrashRecoveryContext CRC;
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004830 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenekca817a3c2010-11-14 17:47:35 +00004831 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004832 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4833 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004834}
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004835
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004836} // end: extern "C"
4837
4838//===----------------------------------------------------------------------===//
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004839// Operations for querying linkage of a cursor.
4840//===----------------------------------------------------------------------===//
4841
4842extern "C" {
4843CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor5272e802010-03-19 05:22:59 +00004844 if (!clang_isDeclaration(cursor.kind))
4845 return CXLinkage_Invalid;
4846
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004847 Decl *D = cxcursor::getCursorDecl(cursor);
4848 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4849 switch (ND->getLinkage()) {
4850 case NoLinkage: return CXLinkage_NoLinkage;
4851 case InternalLinkage: return CXLinkage_Internal;
4852 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4853 case ExternalLinkage: return CXLinkage_External;
4854 };
4855
4856 return CXLinkage_Invalid;
4857}
4858} // end: extern "C"
4859
4860//===----------------------------------------------------------------------===//
Ted Kremenek4ed29252010-04-12 21:22:16 +00004861// Operations for querying language of a cursor.
4862//===----------------------------------------------------------------------===//
4863
4864static CXLanguageKind getDeclLanguage(const Decl *D) {
4865 switch (D->getKind()) {
4866 default:
4867 break;
4868 case Decl::ImplicitParam:
4869 case Decl::ObjCAtDefsField:
4870 case Decl::ObjCCategory:
4871 case Decl::ObjCCategoryImpl:
4872 case Decl::ObjCClass:
4873 case Decl::ObjCCompatibleAlias:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004874 case Decl::ObjCForwardProtocol:
4875 case Decl::ObjCImplementation:
4876 case Decl::ObjCInterface:
4877 case Decl::ObjCIvar:
4878 case Decl::ObjCMethod:
4879 case Decl::ObjCProperty:
4880 case Decl::ObjCPropertyImpl:
4881 case Decl::ObjCProtocol:
4882 return CXLanguage_ObjC;
4883 case Decl::CXXConstructor:
4884 case Decl::CXXConversion:
4885 case Decl::CXXDestructor:
4886 case Decl::CXXMethod:
4887 case Decl::CXXRecord:
4888 case Decl::ClassTemplate:
4889 case Decl::ClassTemplatePartialSpecialization:
4890 case Decl::ClassTemplateSpecialization:
4891 case Decl::Friend:
4892 case Decl::FriendTemplate:
4893 case Decl::FunctionTemplate:
4894 case Decl::LinkageSpec:
4895 case Decl::Namespace:
4896 case Decl::NamespaceAlias:
4897 case Decl::NonTypeTemplateParm:
4898 case Decl::StaticAssert:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004899 case Decl::TemplateTemplateParm:
4900 case Decl::TemplateTypeParm:
4901 case Decl::UnresolvedUsingTypename:
4902 case Decl::UnresolvedUsingValue:
4903 case Decl::Using:
4904 case Decl::UsingDirective:
4905 case Decl::UsingShadow:
4906 return CXLanguage_CPlusPlus;
4907 }
4908
4909 return CXLanguage_C;
4910}
4911
4912extern "C" {
Douglas Gregorf757a122010-08-23 23:00:57 +00004913
4914enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4915 if (clang_isDeclaration(cursor.kind))
4916 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004917 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregorf757a122010-08-23 23:00:57 +00004918 return CXAvailability_Available;
4919
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004920 switch (D->getAvailability()) {
4921 case AR_Available:
4922 case AR_NotYetIntroduced:
4923 return CXAvailability_Available;
4924
4925 case AR_Deprecated:
Douglas Gregorf757a122010-08-23 23:00:57 +00004926 return CXAvailability_Deprecated;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004927
4928 case AR_Unavailable:
4929 return CXAvailability_NotAvailable;
4930 }
Douglas Gregorf757a122010-08-23 23:00:57 +00004931 }
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004932
Douglas Gregorf757a122010-08-23 23:00:57 +00004933 return CXAvailability_Available;
4934}
4935
Ted Kremenek4ed29252010-04-12 21:22:16 +00004936CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4937 if (clang_isDeclaration(cursor.kind))
4938 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4939
4940 return CXLanguage_Invalid;
4941}
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004942
4943 /// \brief If the given cursor is the "templated" declaration
4944 /// descibing a class or function template, return the class or
4945 /// function template.
4946static Decl *maybeGetTemplateCursor(Decl *D) {
4947 if (!D)
4948 return 0;
4949
4950 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4951 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4952 return FunTmpl;
4953
4954 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4955 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4956 return ClassTmpl;
4957
4958 return D;
4959}
4960
Douglas Gregor0576ce72010-09-22 21:22:29 +00004961CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4962 if (clang_isDeclaration(cursor.kind)) {
4963 if (Decl *D = getCursorDecl(cursor)) {
4964 DeclContext *DC = D->getDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004965 if (!DC)
4966 return clang_getNullCursor();
4967
4968 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4969 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004970 }
4971 }
4972
4973 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4974 if (Decl *D = getCursorDecl(cursor))
Ted Kremenek91554282010-11-16 08:15:36 +00004975 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004976 }
4977
4978 return clang_getNullCursor();
4979}
4980
4981CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4982 if (clang_isDeclaration(cursor.kind)) {
4983 if (Decl *D = getCursorDecl(cursor)) {
4984 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004985 if (!DC)
4986 return clang_getNullCursor();
4987
4988 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4989 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004990 }
4991 }
4992
4993 // FIXME: Note that we can't easily compute the lexical context of a
4994 // statement or expression, so we return nothing.
4995 return clang_getNullCursor();
4996}
4997
Douglas Gregor99a26af2010-10-01 20:25:15 +00004998static void CollectOverriddenMethods(DeclContext *Ctx,
4999 ObjCMethodDecl *Method,
5000 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5001 if (!Ctx)
5002 return;
5003
5004 // If we have a class or category implementation, jump straight to the
5005 // interface.
5006 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5007 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5008
5009 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5010 if (!Container)
5011 return;
5012
5013 // Check whether we have a matching method at this level.
5014 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5015 Method->isInstanceMethod()))
5016 if (Method != Overridden) {
5017 // We found an override at this level; there is no need to look
5018 // into other protocols or categories.
5019 Methods.push_back(Overridden);
5020 return;
5021 }
5022
5023 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5024 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5025 PEnd = Protocol->protocol_end();
5026 P != PEnd; ++P)
5027 CollectOverriddenMethods(*P, Method, Methods);
5028 }
5029
5030 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5031 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5032 PEnd = Category->protocol_end();
5033 P != PEnd; ++P)
5034 CollectOverriddenMethods(*P, Method, Methods);
5035 }
5036
5037 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5038 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5039 PEnd = Interface->protocol_end();
5040 P != PEnd; ++P)
5041 CollectOverriddenMethods(*P, Method, Methods);
5042
5043 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5044 Category; Category = Category->getNextClassCategory())
5045 CollectOverriddenMethods(Category, Method, Methods);
5046
5047 // We only look into the superclass if we haven't found anything yet.
5048 if (Methods.empty())
5049 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5050 return CollectOverriddenMethods(Super, Method, Methods);
5051 }
5052}
5053
5054void clang_getOverriddenCursors(CXCursor cursor,
5055 CXCursor **overridden,
5056 unsigned *num_overridden) {
5057 if (overridden)
5058 *overridden = 0;
5059 if (num_overridden)
5060 *num_overridden = 0;
5061 if (!overridden || !num_overridden)
5062 return;
5063
5064 if (!clang_isDeclaration(cursor.kind))
5065 return;
5066
5067 Decl *D = getCursorDecl(cursor);
5068 if (!D)
5069 return;
5070
5071 // Handle C++ member functions.
Ted Kremenek91554282010-11-16 08:15:36 +00005072 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005073 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5074 *num_overridden = CXXMethod->size_overridden_methods();
5075 if (!*num_overridden)
5076 return;
5077
5078 *overridden = new CXCursor [*num_overridden];
5079 unsigned I = 0;
5080 for (CXXMethodDecl::method_iterator
5081 M = CXXMethod->begin_overridden_methods(),
5082 MEnd = CXXMethod->end_overridden_methods();
5083 M != MEnd; (void)++M, ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00005084 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005085 return;
5086 }
5087
5088 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5089 if (!Method)
5090 return;
5091
5092 // Handle Objective-C methods.
5093 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5094 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5095
5096 if (Methods.empty())
5097 return;
5098
5099 *num_overridden = Methods.size();
5100 *overridden = new CXCursor [Methods.size()];
5101 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00005102 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005103}
5104
5105void clang_disposeOverriddenCursors(CXCursor *overridden) {
5106 delete [] overridden;
5107}
5108
Douglas Gregor796d76a2010-10-20 22:00:55 +00005109CXFile clang_getIncludedFile(CXCursor cursor) {
5110 if (cursor.kind != CXCursor_InclusionDirective)
5111 return 0;
5112
5113 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5114 return (void *)ID->getFile();
5115}
5116
Ted Kremenek4ed29252010-04-12 21:22:16 +00005117} // end: extern "C"
5118
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005119
5120//===----------------------------------------------------------------------===//
5121// C++ AST instrospection.
5122//===----------------------------------------------------------------------===//
5123
5124extern "C" {
5125unsigned clang_CXXMethod_isStatic(CXCursor C) {
5126 if (!clang_isDeclaration(C.kind))
5127 return 0;
Douglas Gregorf11309e2010-08-31 22:12:17 +00005128
5129 CXXMethodDecl *Method = 0;
5130 Decl *D = cxcursor::getCursorDecl(C);
5131 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5132 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5133 else
5134 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5135 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek0ed75492010-05-17 20:12:45 +00005136}
Ted Kremeneka10f1282010-05-18 22:32:15 +00005137
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005138} // end: extern "C"
5139
Ted Kremenek4ed29252010-04-12 21:22:16 +00005140//===----------------------------------------------------------------------===//
Ted Kremeneka5940822010-08-26 01:42:22 +00005141// Attribute introspection.
5142//===----------------------------------------------------------------------===//
5143
5144extern "C" {
5145CXType clang_getIBOutletCollectionType(CXCursor C) {
5146 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremenek91554282010-11-16 08:15:36 +00005147 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005148
5149 IBOutletCollectionAttr *A =
5150 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5151
Douglas Gregorc81a7a22011-03-06 18:55:32 +00005152 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005153}
5154} // end: extern "C"
5155
5156//===----------------------------------------------------------------------===//
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005157// Misc. utility functions.
5158//===----------------------------------------------------------------------===//
Ted Kremenekf441baf2010-02-17 00:41:40 +00005159
Daniel Dunbar087c3a32010-11-05 17:21:46 +00005160/// Default to using an 8 MB stack size on "safety" threads.
5161static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005162
5163namespace clang {
5164
5165bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenekca817a3c2010-11-14 17:47:35 +00005166 void (*Fn)(void*), void *UserData,
5167 unsigned Size) {
5168 if (!Size)
5169 Size = GetSafetyThreadStackSize();
5170 if (Size)
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005171 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5172 return CRC.RunSafely(Fn, UserData);
5173}
5174
5175unsigned GetSafetyThreadStackSize() {
5176 return SafetyStackThreadSize;
5177}
5178
5179void SetSafetyThreadStackSize(unsigned Value) {
5180 SafetyStackThreadSize = Value;
5181}
5182
5183}
5184
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005185extern "C" {
5186
Ted Kremeneka3e65702010-02-12 22:54:40 +00005187CXString clang_getClangVersion() {
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00005188 return createCXString(getClangFullVersion());
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005189}
5190
5191} // end: extern "C"