blob: 870e6b20187d146a5f9ad557877c4070ef2f107c [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())
Douglas Gregor07542c52011-04-20 21:16:21 +0000119 EndLoc = SM.getInstantiationRange(EndLoc).second;
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
Richard Smithdda56e42011-04-15 14:24:37 +0000275 bool VisitTypeAliasDecl(TypeAliasDecl *D);
Ted Kremenek6ab9aa022010-02-18 05:46:33 +0000276 bool VisitAttributes(Decl *D);
Ted Kremenek33b9a422010-04-11 21:47:37 +0000277 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenekae9e2212010-08-27 21:34:58 +0000278 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd40a4392010-11-02 23:10:24 +0000279 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregor71f3d942010-01-20 20:59:29 +0000280 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek7dff4162010-02-18 18:47:08 +0000281 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
282 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000283 bool VisitTagDecl(TagDecl *D);
Douglas Gregor9dc243c2010-09-01 17:32:36 +0000284 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregorf96abb22010-08-31 19:31:58 +0000285 bool VisitClassTemplatePartialSpecializationDecl(
286 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregor713602b2010-08-31 17:01:39 +0000287 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000288 bool VisitEnumConstantDecl(EnumConstantDecl *D);
289 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
290 bool VisitFunctionDecl(FunctionDecl *ND);
291 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek7dff4162010-02-18 18:47:08 +0000292 bool VisitVarDecl(VarDecl *);
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000293 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregor713602b2010-08-31 17:01:39 +0000294 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor1fbaeb12010-08-31 19:02:00 +0000295 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000296 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000297 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
298 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
299 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
300 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek49be9e02010-05-18 21:09:07 +0000301 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremeneke2110252010-02-18 22:36:18 +0000302 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
303 bool VisitObjCImplDecl(ObjCImplDecl *D);
304 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
305 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000306 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
307 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
308 bool VisitObjCClassDecl(ObjCClassDecl *D);
Douglas Gregorb1b71e52010-11-17 01:03:52 +0000309 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
Ted Kremenekb80cba52010-05-07 01:04:29 +0000310 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenekbd67fb22010-05-06 23:38:21 +0000311 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregora89314e2010-08-31 23:48:11 +0000312 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor01a430132010-09-01 03:07:18 +0000313 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregora9aa29c2010-09-01 19:52:22 +0000314 bool VisitUsingDecl(UsingDecl *D);
315 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
316 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor01a430132010-09-01 03:07:18 +0000317
Douglas Gregor12bca222010-08-31 14:41:23 +0000318 // Name visitor
319 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregor3335f482010-09-02 17:35:32 +0000320 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregora9d87bc2011-02-25 00:36:19 +0000321 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
Douglas Gregor12bca222010-08-31 14:41:23 +0000322
Douglas Gregor713602b2010-08-31 17:01:39 +0000323 // Template visitors
324 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregora23e8f72010-08-31 20:37:03 +0000325 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregor713602b2010-08-31 17:01:39 +0000326 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
327
Douglas Gregor93f89952010-01-21 16:28:34 +0000328 // Type visitors
Douglas Gregor12bca222010-08-31 14:41:23 +0000329 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000330 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor93f89952010-01-21 16:28:34 +0000331 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000332 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
333 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregor713602b2010-08-31 17:01:39 +0000334 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000335 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCall8b07ec22010-05-15 11:32:37 +0000336 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000337 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
Abramo Bagnara924a8f32010-12-10 16:29:40 +0000338 bool VisitParenTypeLoc(ParenTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000339 bool VisitPointerTypeLoc(PointerTypeLoc TL);
340 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
341 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
342 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
343 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor12bca222010-08-31 14:41:23 +0000344 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregord1824312010-01-21 17:29:07 +0000345 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregor713602b2010-08-31 17:01:39 +0000346 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor6479fc42010-01-21 20:48:56 +0000347 // FIXME: Implement visitors here when the unimplemented TypeLocs get
348 // implemented
349 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
Douglas Gregord2fa7662010-12-20 02:24:11 +0000350 bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
Douglas Gregor6479fc42010-01-21 20:48:56 +0000351 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Douglas Gregor3d0da5f2011-03-01 01:34:45 +0000352 bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
Douglas Gregora7a795b2011-03-01 20:11:18 +0000353 bool VisitDependentTemplateSpecializationTypeLoc(
354 DependentTemplateSpecializationTypeLoc TL);
Douglas Gregor844cb502011-03-01 18:12:44 +0000355 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
Douglas Gregor3d0da5f2011-03-01 01:34:45 +0000356
Ted Kremenek92209a42010-11-11 08:05:18 +0000357 // Data-recursive visitor functions.
358 bool IsInRegionOfInterest(CXCursor C);
359 bool RunVisitorWorkList(VisitorWorkList &WL);
360 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
Ted Kremenek5d304a32010-11-18 00:42:18 +0000361 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
Steve Naroff1054e602009-08-31 00:59:03 +0000362};
Ted Kremenekf441baf2010-02-17 00:41:40 +0000363
Ted Kremenek0ec2cca2010-01-05 19:32:54 +0000364} // end anonymous namespace
Benjamin Kramer61f5d0c2009-10-18 16:11:04 +0000365
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000366static SourceRange getRawCursorExtent(CXCursor C);
Douglas Gregor29ee4222010-11-17 17:14:07 +0000367static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
368
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000369
Douglas Gregor562c1f92010-01-22 19:49:59 +0000370RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Ted Kremenek91554282010-11-16 08:15:36 +0000371 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
Douglas Gregor562c1f92010-01-22 19:49:59 +0000372}
373
Douglas Gregor71f3d942010-01-20 20:59:29 +0000374/// \brief Visit the given cursor and, if requested by the visitor,
375/// its children.
376///
Douglas Gregor562c1f92010-01-22 19:49:59 +0000377/// \param Cursor the cursor to visit.
378///
379/// \param CheckRegionOfInterest if true, then the caller already checked that
380/// this cursor is within the region of interest.
381///
Douglas Gregor71f3d942010-01-20 20:59:29 +0000382/// \returns true if the visitation should be aborted, false if it
383/// should continue.
Douglas Gregor562c1f92010-01-22 19:49:59 +0000384bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregor71f3d942010-01-20 20:59:29 +0000385 if (clang_isInvalid(Cursor.kind))
386 return false;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000387
Douglas Gregor71f3d942010-01-20 20:59:29 +0000388 if (clang_isDeclaration(Cursor.kind)) {
389 Decl *D = getCursorDecl(Cursor);
390 assert(D && "Invalid declaration cursor");
391 if (D->getPCHLevel() > MaxPCHLevel)
392 return false;
393
394 if (D->isImplicit())
395 return false;
396 }
397
Douglas Gregor562c1f92010-01-22 19:49:59 +0000398 // If we have a range of interest, and this cursor doesn't intersect with it,
399 // we're done.
400 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000401 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbar2f4ba172010-02-14 08:32:05 +0000402 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor562c1f92010-01-22 19:49:59 +0000403 return false;
404 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000405
Douglas Gregor71f3d942010-01-20 20:59:29 +0000406 switch (Visitor(Cursor, Parent, ClientData)) {
407 case CXChildVisit_Break:
408 return true;
409
410 case CXChildVisit_Continue:
411 return false;
412
413 case CXChildVisit_Recurse:
414 return VisitChildren(Cursor);
415 }
416
Douglas Gregor33f16852010-01-25 16:45:46 +0000417 return false;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000418}
419
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000420std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
421CursorVisitor::getPreprocessedEntities() {
422 PreprocessingRecord &PPRec
Ted Kremenek91554282010-11-16 08:15:36 +0000423 = *AU->getPreprocessor().getPreprocessingRecord();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000424
425 bool OnlyLocalDecls
Douglas Gregorfd4da712010-12-21 19:07:48 +0000426 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
427
428 if (OnlyLocalDecls && RegionOfInterest.isValid()) {
429 // If we would only look at local declarations but we have a region of
430 // interest, check whether that region of interest is in the main file.
431 // If not, we should traverse all declarations.
432 // FIXME: My kingdom for a proper binary search approach to finding
433 // cursors!
434 std::pair<FileID, unsigned> Location
435 = AU->getSourceManager().getDecomposedInstantiationLoc(
436 RegionOfInterest.getBegin());
437 if (Location.first != AU->getSourceManager().getMainFileID())
438 OnlyLocalDecls = false;
439 }
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000440
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000441 PreprocessingRecord::iterator StartEntity, EndEntity;
442 if (OnlyLocalDecls) {
443 StartEntity = AU->pp_entity_begin();
444 EndEntity = AU->pp_entity_end();
445 } else {
446 StartEntity = PPRec.begin();
447 EndEntity = PPRec.end();
448 }
449
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000450 // There is no region of interest; we have to walk everything.
451 if (RegionOfInterest.isInvalid())
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000452 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000453
454 // Find the file in which the region of interest lands.
Ted Kremenek91554282010-11-16 08:15:36 +0000455 SourceManager &SM = AU->getSourceManager();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000456 std::pair<FileID, unsigned> Begin
457 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
458 std::pair<FileID, unsigned> End
459 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
460
461 // The region of interest spans files; we have to walk everything.
462 if (Begin.first != End.first)
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000463 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000464
465 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
Ted Kremenek91554282010-11-16 08:15:36 +0000466 = AU->getPreprocessedEntitiesByFile();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000467 if (ByFileMap.empty()) {
468 // Build the mapping from files to sets of preprocessed entities.
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000469 for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000470 std::pair<FileID, unsigned> P
471 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000472
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000473 ByFileMap[P.first].push_back(*E);
474 }
475 }
476
477 return std::make_pair(ByFileMap[Begin.first].begin(),
478 ByFileMap[Begin.first].end());
479}
480
Douglas Gregor71f3d942010-01-20 20:59:29 +0000481/// \brief Visit the children of the given cursor.
Ted Kremenek91554282010-11-16 08:15:36 +0000482///
Douglas Gregor71f3d942010-01-20 20:59:29 +0000483/// \returns true if the visitation should be aborted, false if it
484/// should continue.
Ted Kremenekf441baf2010-02-17 00:41:40 +0000485bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregor64f38ae2011-03-02 19:17:03 +0000486 if (clang_isReference(Cursor.kind) &&
487 Cursor.kind != CXCursor_CXXBaseSpecifier) {
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000488 // By definition, references have no children.
489 return false;
490 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000491
492 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregor71f3d942010-01-20 20:59:29 +0000493 // done.
Ted Kremenek12e0f292010-05-13 00:25:00 +0000494 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf441baf2010-02-17 00:41:40 +0000495
Douglas Gregor71f3d942010-01-20 20:59:29 +0000496 if (clang_isDeclaration(Cursor.kind)) {
497 Decl *D = getCursorDecl(Cursor);
Douglas Gregor7df21262011-04-14 21:41:34 +0000498 if (!D)
499 return false;
500
Ted Kremenek0e293092010-02-18 18:47:01 +0000501 return VisitAttributes(D) || Visit(D);
Douglas Gregor71f3d942010-01-20 20:59:29 +0000502 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000503
Douglas Gregor7df21262011-04-14 21:41:34 +0000504 if (clang_isStatement(Cursor.kind)) {
505 if (Stmt *S = getCursorStmt(Cursor))
506 return Visit(S);
507
508 return false;
509 }
510
511 if (clang_isExpression(Cursor.kind)) {
512 if (Expr *E = getCursorExpr(Cursor))
513 return Visit(E);
514
515 return false;
516 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000517
Douglas Gregor71f3d942010-01-20 20:59:29 +0000518 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremenek91554282010-11-16 08:15:36 +0000519 CXTranslationUnit tu = getCursorTU(Cursor);
520 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregorc2b97992011-03-16 23:23:30 +0000521
522 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
523 for (unsigned I = 0; I != 2; ++I) {
524 if (VisitOrder[I]) {
525 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
526 RegionOfInterest.isInvalid()) {
527 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
528 TLEnd = CXXUnit->top_level_end();
529 TL != TLEnd; ++TL) {
530 if (Visit(MakeCXCursor(*TL, tu), true))
531 return true;
532 }
533 } else if (VisitDeclContext(
534 CXXUnit->getASTContext().getTranslationUnitDecl()))
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000535 return true;
Douglas Gregorc2b97992011-03-16 23:23:30 +0000536 continue;
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000537 }
Bob Wilson4f559a32010-03-19 03:57:57 +0000538
Douglas Gregorc2b97992011-03-16 23:23:30 +0000539 // Walk the preprocessing record.
540 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
541 // FIXME: Once we have the ability to deserialize a preprocessing record,
542 // do so.
543 PreprocessingRecord::iterator E, EEnd;
544 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
545 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
546 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
547 return true;
548
549 continue;
550 }
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000551
Douglas Gregorc2b97992011-03-16 23:23:30 +0000552 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
553 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
554 return true;
555
556 continue;
557 }
Douglas Gregor5272e802010-03-19 05:22:59 +0000558
Douglas Gregorc2b97992011-03-16 23:23:30 +0000559 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
560 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
561 return true;
562
563 continue;
564 }
Douglas Gregor796d76a2010-10-20 22:00:55 +0000565 }
Douglas Gregor5272e802010-03-19 05:22:59 +0000566 }
567 }
Douglas Gregorc2b97992011-03-16 23:23:30 +0000568
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000569 return false;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000570 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000571
Douglas Gregor64f38ae2011-03-02 19:17:03 +0000572 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
573 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
574 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
575 return Visit(BaseTSInfo->getTypeLoc());
576 }
577 }
578 }
579
Douglas Gregor71f3d942010-01-20 20:59:29 +0000580 // Nothing to visit at the moment.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000581 return false;
582}
583
Ted Kremenek33b9a422010-04-11 21:47:37 +0000584bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
John McCalla3cecb62010-06-04 22:33:30 +0000585 if (Visit(B->getSignatureAsWritten()->getTypeLoc()))
586 return true;
Ted Kremenek33b9a422010-04-11 21:47:37 +0000587
Ted Kremenek60fe71a2010-07-22 11:30:19 +0000588 if (Stmt *Body = B->getBody())
589 return Visit(MakeCXCursor(Body, StmtParent, TU));
590
591 return false;
Ted Kremenek33b9a422010-04-11 21:47:37 +0000592}
593
Ted Kremenekd40a4392010-11-02 23:10:24 +0000594llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
595 if (RegionOfInterest.isValid()) {
Douglas Gregor29ee4222010-11-17 17:14:07 +0000596 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd40a4392010-11-02 23:10:24 +0000597 if (Range.isInvalid())
598 return llvm::Optional<bool>();
Douglas Gregor29ee4222010-11-17 17:14:07 +0000599
Ted Kremenekd40a4392010-11-02 23:10:24 +0000600 switch (CompareRegionOfInterest(Range)) {
601 case RangeBefore:
602 // This declaration comes before the region of interest; skip it.
603 return llvm::Optional<bool>();
604
605 case RangeAfter:
606 // This declaration comes after the region of interest; we're done.
607 return false;
608
609 case RangeOverlap:
610 // This declaration overlaps the region of interest; visit it.
611 break;
612 }
613 }
614 return true;
615}
616
617bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
618 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
619
620 // FIXME: Eventually remove. This part of a hack to support proper
621 // iteration over all Decls contained lexically within an ObjC container.
622 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
623 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
624
625 for ( ; I != E; ++I) {
Ted Kremenek49be9e02010-05-18 21:09:07 +0000626 Decl *D = *I;
627 if (D->getLexicalDeclContext() != DC)
628 continue;
Ted Kremenek49be9e02010-05-18 21:09:07 +0000629 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd40a4392010-11-02 23:10:24 +0000630 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
631 if (!V.hasValue())
632 continue;
633 if (!V.getValue())
634 return false;
Daniel Dunbar02968e52010-02-14 10:02:57 +0000635 if (Visit(Cursor, true))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000636 return true;
637 }
Douglas Gregor71f3d942010-01-20 20:59:29 +0000638 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +0000639}
640
Douglas Gregord824f882010-01-22 00:50:27 +0000641bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
642 llvm_unreachable("Translation units are visited directly by Visit()");
643 return false;
644}
645
Richard Smithdda56e42011-04-15 14:24:37 +0000646bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
647 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
648 return Visit(TSInfo->getTypeLoc());
649
650 return false;
651}
652
Douglas Gregord824f882010-01-22 00:50:27 +0000653bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
654 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
655 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf441baf2010-02-17 00:41:40 +0000656
Douglas Gregord824f882010-01-22 00:50:27 +0000657 return false;
658}
659
660bool CursorVisitor::VisitTagDecl(TagDecl *D) {
661 return VisitDeclContext(D);
662}
663
Douglas Gregor9dc243c2010-09-01 17:32:36 +0000664bool CursorVisitor::VisitClassTemplateSpecializationDecl(
665 ClassTemplateSpecializationDecl *D) {
666 bool ShouldVisitBody = false;
667 switch (D->getSpecializationKind()) {
668 case TSK_Undeclared:
669 case TSK_ImplicitInstantiation:
670 // Nothing to visit
671 return false;
672
673 case TSK_ExplicitInstantiationDeclaration:
674 case TSK_ExplicitInstantiationDefinition:
675 break;
676
677 case TSK_ExplicitSpecialization:
678 ShouldVisitBody = true;
679 break;
680 }
681
682 // Visit the template arguments used in the specialization.
683 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
684 TypeLoc TL = SpecType->getTypeLoc();
685 if (TemplateSpecializationTypeLoc *TSTLoc
686 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
687 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
688 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
689 return true;
690 }
691 }
692
693 if (ShouldVisitBody && VisitCXXRecordDecl(D))
694 return true;
695
696 return false;
697}
698
Douglas Gregorf96abb22010-08-31 19:31:58 +0000699bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
700 ClassTemplatePartialSpecializationDecl *D) {
701 // FIXME: Visit the "outer" template parameter lists on the TagDecl
702 // before visiting these template parameters.
703 if (VisitTemplateParameters(D->getTemplateParameters()))
704 return true;
705
706 // Visit the partial specialization arguments.
707 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
708 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
710 return true;
711
712 return VisitCXXRecordDecl(D);
713}
714
Douglas Gregor713602b2010-08-31 17:01:39 +0000715bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000716 // Visit the default argument.
717 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
718 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
719 if (Visit(DefArg->getTypeLoc()))
720 return true;
721
Douglas Gregor713602b2010-08-31 17:01:39 +0000722 return false;
723}
724
Douglas Gregord824f882010-01-22 00:50:27 +0000725bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
726 if (Expr *Init = D->getInitExpr())
727 return Visit(MakeCXCursor(Init, StmtParent, TU));
728 return false;
729}
730
Douglas Gregor93f89952010-01-21 16:28:34 +0000731bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
732 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
733 if (Visit(TSInfo->getTypeLoc()))
734 return true;
735
Douglas Gregor14454802011-02-25 02:25:35 +0000736 // Visit the nested-name-specifier, if present.
737 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
738 if (VisitNestedNameSpecifierLoc(QualifierLoc))
739 return true;
740
Douglas Gregor93f89952010-01-21 16:28:34 +0000741 return false;
742}
743
Douglas Gregorf3af3112010-09-09 21:42:20 +0000744/// \brief Compare two base or member initializers based on their source order.
Alexis Hunt1d792652011-01-08 20:30:50 +0000745static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
746 CXXCtorInitializer const * const *X
747 = static_cast<CXXCtorInitializer const * const *>(Xp);
748 CXXCtorInitializer const * const *Y
749 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregorf3af3112010-09-09 21:42:20 +0000750
751 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
752 return -1;
753 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
754 return 1;
755 else
756 return 0;
757}
758
Douglas Gregor71f3d942010-01-20 20:59:29 +0000759bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor12bca222010-08-31 14:41:23 +0000760 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
761 // Visit the function declaration's syntactic components in the order
762 // written. This requires a bit of work.
Abramo Bagnara6d810632010-12-14 22:11:44 +0000763 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor12bca222010-08-31 14:41:23 +0000764 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
765
766 // If we have a function declared directly (without the use of a typedef),
767 // visit just the return type. Otherwise, just visit the function's type
768 // now.
769 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
770 (!FTL && Visit(TL)))
771 return true;
772
Douglas Gregor3335f482010-09-02 17:35:32 +0000773 // Visit the nested-name-specifier, if present.
Douglas Gregor14454802011-02-25 02:25:35 +0000774 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
775 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +0000776 return true;
Douglas Gregor12bca222010-08-31 14:41:23 +0000777
778 // Visit the declaration name.
779 if (VisitDeclarationNameInfo(ND->getNameInfo()))
780 return true;
781
782 // FIXME: Visit explicitly-specified template arguments!
783
784 // Visit the function parameters, if we have a function type.
785 if (FTL && VisitFunctionTypeLoc(*FTL, true))
786 return true;
787
788 // FIXME: Attributes?
789 }
790
Douglas Gregorf3af3112010-09-09 21:42:20 +0000791 if (ND->isThisDeclarationADefinition()) {
792 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
793 // Find the initializers that were written in the source.
Alexis Hunt1d792652011-01-08 20:30:50 +0000794 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregorf3af3112010-09-09 21:42:20 +0000795 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
796 IEnd = Constructor->init_end();
797 I != IEnd; ++I) {
798 if (!(*I)->isWritten())
799 continue;
800
801 WrittenInits.push_back(*I);
802 }
803
804 // Sort the initializers in source order
805 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Alexis Hunt1d792652011-01-08 20:30:50 +0000806 &CompareCXXCtorInitializers);
Douglas Gregorf3af3112010-09-09 21:42:20 +0000807
808 // Visit the initializers in source order
809 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Alexis Hunt1d792652011-01-08 20:30:50 +0000810 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichetd583da02010-12-04 09:14:42 +0000811 if (Init->isAnyMemberInitializer()) {
812 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregorf3af3112010-09-09 21:42:20 +0000813 Init->getMemberLocation(), TU)))
814 return true;
815 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
816 if (Visit(BaseInfo->getTypeLoc()))
817 return true;
818 }
819
820 // Visit the initializer value.
821 if (Expr *Initializer = Init->getInit())
822 if (Visit(MakeCXCursor(Initializer, ND, TU)))
823 return true;
824 }
825 }
826
827 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
828 return true;
829 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000830
Douglas Gregor71f3d942010-01-20 20:59:29 +0000831 return false;
832}
Ted Kremenek78668fd2010-01-13 00:22:49 +0000833
Douglas Gregord824f882010-01-22 00:50:27 +0000834bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
835 if (VisitDeclaratorDecl(D))
836 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000837
Douglas Gregord824f882010-01-22 00:50:27 +0000838 if (Expr *BitWidth = D->getBitWidth())
839 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf441baf2010-02-17 00:41:40 +0000840
Douglas Gregord824f882010-01-22 00:50:27 +0000841 return false;
842}
843
844bool CursorVisitor::VisitVarDecl(VarDecl *D) {
845 if (VisitDeclaratorDecl(D))
846 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000847
Douglas Gregord824f882010-01-22 00:50:27 +0000848 if (Expr *Init = D->getInit())
849 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf441baf2010-02-17 00:41:40 +0000850
Douglas Gregord824f882010-01-22 00:50:27 +0000851 return false;
852}
853
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000854bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
855 if (VisitDeclaratorDecl(D))
856 return true;
857
858 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
859 if (Expr *DefArg = D->getDefaultArgument())
860 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
861
862 return false;
863}
864
Douglas Gregor713602b2010-08-31 17:01:39 +0000865bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
866 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
867 // before visiting these template parameters.
868 if (VisitTemplateParameters(D->getTemplateParameters()))
869 return true;
870
871 return VisitFunctionDecl(D->getTemplatedDecl());
872}
873
Douglas Gregor1fbaeb12010-08-31 19:02:00 +0000874bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
875 // FIXME: Visit the "outer" template parameter lists on the TagDecl
876 // before visiting these template parameters.
877 if (VisitTemplateParameters(D->getTemplateParameters()))
878 return true;
879
880 return VisitCXXRecordDecl(D->getTemplatedDecl());
881}
882
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000883bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
884 if (VisitTemplateParameters(D->getTemplateParameters()))
885 return true;
886
887 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
888 VisitTemplateArgumentLoc(D->getDefaultArgument()))
889 return true;
890
891 return false;
892}
893
Douglas Gregord824f882010-01-22 00:50:27 +0000894bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor12852d92010-03-08 14:59:44 +0000895 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
896 if (Visit(TSInfo->getTypeLoc()))
897 return true;
898
Ted Kremenekf441baf2010-02-17 00:41:40 +0000899 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregord824f882010-01-22 00:50:27 +0000900 PEnd = ND->param_end();
901 P != PEnd; ++P) {
902 if (Visit(MakeCXCursor(*P, TU)))
903 return true;
904 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000905
Douglas Gregord824f882010-01-22 00:50:27 +0000906 if (ND->isThisDeclarationADefinition() &&
907 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
908 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000909
Douglas Gregord824f882010-01-22 00:50:27 +0000910 return false;
911}
912
Ted Kremenekd40a4392010-11-02 23:10:24 +0000913namespace {
914 struct ContainerDeclsSort {
915 SourceManager &SM;
916 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
917 bool operator()(Decl *A, Decl *B) {
918 SourceLocation L_A = A->getLocStart();
919 SourceLocation L_B = B->getLocStart();
920 assert(L_A.isValid() && L_B.isValid());
921 return SM.isBeforeInTranslationUnit(L_A, L_B);
922 }
923 };
924}
925
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000926bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd40a4392010-11-02 23:10:24 +0000927 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
928 // an @implementation can lexically contain Decls that are not properly
929 // nested in the AST. When we identify such cases, we need to retrofit
930 // this nesting here.
931 if (!DI_current)
932 return VisitDeclContext(D);
933
934 // Scan the Decls that immediately come after the container
935 // in the current DeclContext. If any fall within the
936 // container's lexical region, stash them into a vector
937 // for later processing.
938 llvm::SmallVector<Decl *, 24> DeclsInContainer;
939 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremenek91554282010-11-16 08:15:36 +0000940 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd40a4392010-11-02 23:10:24 +0000941 if (EndLoc.isValid()) {
942 DeclContext::decl_iterator next = *DI_current;
943 while (++next != DE_current) {
944 Decl *D_next = *next;
945 if (!D_next)
946 break;
947 SourceLocation L = D_next->getLocStart();
948 if (!L.isValid())
949 break;
950 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
951 *DI_current = next;
952 DeclsInContainer.push_back(D_next);
953 continue;
954 }
955 break;
956 }
957 }
958
959 // The common case.
960 if (DeclsInContainer.empty())
961 return VisitDeclContext(D);
962
963 // Get all the Decls in the DeclContext, and sort them with the
964 // additional ones we've collected. Then visit them.
965 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
966 I!=E; ++I) {
967 Decl *subDecl = *I;
Ted Kremenek4bd4d752010-11-02 23:17:51 +0000968 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
969 subDecl->getLocStart().isInvalid())
Ted Kremenekd40a4392010-11-02 23:10:24 +0000970 continue;
971 DeclsInContainer.push_back(subDecl);
972 }
973
974 // Now sort the Decls so that they appear in lexical order.
975 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
976 ContainerDeclsSort(SM));
977
978 // Now visit the decls.
979 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
980 E = DeclsInContainer.end(); I != E; ++I) {
981 CXCursor Cursor = MakeCXCursor(*I, TU);
982 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
983 if (!V.hasValue())
984 continue;
985 if (!V.getValue())
986 return false;
987 if (Visit(Cursor, true))
988 return true;
989 }
990 return false;
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000991}
992
Douglas Gregor71f3d942010-01-20 20:59:29 +0000993bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorfed36b12010-01-20 23:57:43 +0000994 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
995 TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000996 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000997
Douglas Gregoref6eb842010-01-16 15:44:18 +0000998 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
999 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1000 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +00001001 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001002 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001003
Douglas Gregor5e8cf372010-01-21 23:27:09 +00001004 return VisitObjCContainerDecl(ND);
Ted Kremenek78668fd2010-01-13 00:22:49 +00001005}
1006
Douglas Gregord824f882010-01-22 00:50:27 +00001007bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1008 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1009 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1010 E = PID->protocol_end(); I != E; ++I, ++PL)
1011 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1012 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001013
Douglas Gregord824f882010-01-22 00:50:27 +00001014 return VisitObjCContainerDecl(PID);
1015}
1016
Ted Kremenek49be9e02010-05-18 21:09:07 +00001017bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor9f0e1aa2010-09-09 17:09:21 +00001018 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCalla3cecb62010-06-04 22:33:30 +00001019 return true;
1020
Ted Kremenek49be9e02010-05-18 21:09:07 +00001021 // FIXME: This implements a workaround with @property declarations also being
1022 // installed in the DeclContext for the @interface. Eventually this code
1023 // should be removed.
1024 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1025 if (!CDecl || !CDecl->IsClassExtension())
1026 return false;
1027
1028 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1029 if (!ID)
1030 return false;
1031
1032 IdentifierInfo *PropertyId = PD->getIdentifier();
1033 ObjCPropertyDecl *prevDecl =
1034 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1035
1036 if (!prevDecl)
1037 return false;
1038
1039 // Visit synthesized methods since they will be skipped when visiting
1040 // the @interface.
1041 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremenek2f075632010-09-21 20:52:59 +00001042 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek49be9e02010-05-18 21:09:07 +00001043 if (Visit(MakeCXCursor(MD, TU)))
1044 return true;
1045
1046 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremenek2f075632010-09-21 20:52:59 +00001047 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek49be9e02010-05-18 21:09:07 +00001048 if (Visit(MakeCXCursor(MD, TU)))
1049 return true;
1050
1051 return false;
1052}
1053
Douglas Gregor71f3d942010-01-20 20:59:29 +00001054bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenek78668fd2010-01-13 00:22:49 +00001055 // Issue callbacks for super class.
Douglas Gregor71f3d942010-01-20 20:59:29 +00001056 if (D->getSuperClass() &&
1057 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf441baf2010-02-17 00:41:40 +00001058 D->getSuperClassLoc(),
Douglas Gregorfed36b12010-01-20 23:57:43 +00001059 TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001060 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001061
Douglas Gregoref6eb842010-01-16 15:44:18 +00001062 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1063 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1064 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +00001065 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001066 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001067
Douglas Gregor5e8cf372010-01-21 23:27:09 +00001068 return VisitObjCContainerDecl(D);
Ted Kremenek78668fd2010-01-13 00:22:49 +00001069}
1070
Douglas Gregord824f882010-01-22 00:50:27 +00001071bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1072 return VisitObjCContainerDecl(D);
Ted Kremenek78668fd2010-01-13 00:22:49 +00001073}
1074
Douglas Gregord824f882010-01-22 00:50:27 +00001075bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremeneke184ac52010-03-19 20:39:03 +00001076 // 'ID' could be null when dealing with invalid code.
1077 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1078 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1079 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001080
Douglas Gregord824f882010-01-22 00:50:27 +00001081 return VisitObjCImplDecl(D);
1082}
1083
1084bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1085#if 0
1086 // Issue callbacks for super class.
1087 // FIXME: No source location information!
1088 if (D->getSuperClass() &&
1089 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf441baf2010-02-17 00:41:40 +00001090 D->getSuperClassLoc(),
Douglas Gregord824f882010-01-22 00:50:27 +00001091 TU)))
1092 return true;
1093#endif
Ted Kremenekf441baf2010-02-17 00:41:40 +00001094
Douglas Gregord824f882010-01-22 00:50:27 +00001095 return VisitObjCImplDecl(D);
1096}
1097
1098bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1099 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1100 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1101 E = D->protocol_end();
1102 I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +00001103 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001104 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001105
1106 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +00001107}
1108
Douglas Gregord824f882010-01-22 00:50:27 +00001109bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1110 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1111 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1112 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001113
Douglas Gregord824f882010-01-22 00:50:27 +00001114 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +00001115}
1116
Douglas Gregorb1b71e52010-11-17 01:03:52 +00001117bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1118 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1119 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1120
1121 return false;
1122}
1123
Ted Kremenekbd67fb22010-05-06 23:38:21 +00001124bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1125 return VisitDeclContext(D);
1126}
1127
Douglas Gregora89314e2010-08-31 23:48:11 +00001128bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001129 // Visit nested-name-specifier.
Douglas Gregorc05ba2e2011-02-25 17:08:07 +00001130 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1131 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001132 return true;
Douglas Gregora89314e2010-08-31 23:48:11 +00001133
1134 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1135 D->getTargetNameLoc(), TU));
1136}
1137
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001138bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001139 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001140 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1141 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001142 return true;
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001143 }
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001144
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001145 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1146 return true;
1147
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001148 return VisitDeclarationNameInfo(D->getNameInfo());
1149}
1150
Douglas Gregor01a430132010-09-01 03:07:18 +00001151bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001152 // Visit nested-name-specifier.
Douglas Gregor12441b32011-02-25 16:33:46 +00001153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001155 return true;
Douglas Gregor01a430132010-09-01 03:07:18 +00001156
1157 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1158 D->getIdentLocation(), TU));
1159}
1160
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001161bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001162 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001163 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1164 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001165 return true;
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001166 }
Douglas Gregor3335f482010-09-02 17:35:32 +00001167
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001168 return VisitDeclarationNameInfo(D->getNameInfo());
1169}
1170
1171bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1172 UnresolvedUsingTypenameDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001173 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001174 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1175 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001176 return true;
1177
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001178 return false;
1179}
1180
Douglas Gregor12bca222010-08-31 14:41:23 +00001181bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1182 switch (Name.getName().getNameKind()) {
1183 case clang::DeclarationName::Identifier:
1184 case clang::DeclarationName::CXXLiteralOperatorName:
1185 case clang::DeclarationName::CXXOperatorName:
1186 case clang::DeclarationName::CXXUsingDirective:
1187 return false;
1188
1189 case clang::DeclarationName::CXXConstructorName:
1190 case clang::DeclarationName::CXXDestructorName:
1191 case clang::DeclarationName::CXXConversionFunctionName:
1192 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1193 return Visit(TSInfo->getTypeLoc());
1194 return false;
1195
1196 case clang::DeclarationName::ObjCZeroArgSelector:
1197 case clang::DeclarationName::ObjCOneArgSelector:
1198 case clang::DeclarationName::ObjCMultiArgSelector:
1199 // FIXME: Per-identifier location info?
1200 return false;
1201 }
1202
1203 return false;
1204}
1205
Douglas Gregor3335f482010-09-02 17:35:32 +00001206bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1207 SourceRange Range) {
1208 // FIXME: This whole routine is a hack to work around the lack of proper
1209 // source information in nested-name-specifiers (PR5791). Since we do have
1210 // a beginning source location, we can visit the first component of the
1211 // nested-name-specifier, if it's a single-token component.
1212 if (!NNS)
1213 return false;
1214
1215 // Get the first component in the nested-name-specifier.
1216 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1217 NNS = Prefix;
1218
1219 switch (NNS->getKind()) {
1220 case NestedNameSpecifier::Namespace:
Douglas Gregor3335f482010-09-02 17:35:32 +00001221 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1222 TU));
1223
Douglas Gregor7b26ff92011-02-24 02:36:08 +00001224 case NestedNameSpecifier::NamespaceAlias:
1225 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1226 Range.getBegin(), TU));
1227
Douglas Gregor3335f482010-09-02 17:35:32 +00001228 case NestedNameSpecifier::TypeSpec: {
1229 // If the type has a form where we know that the beginning of the source
1230 // range matches up with a reference cursor. Visit the appropriate reference
1231 // cursor.
John McCall424cec92011-01-19 06:33:43 +00001232 const Type *T = NNS->getAsType();
Douglas Gregor3335f482010-09-02 17:35:32 +00001233 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1234 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1235 if (const TagType *Tag = dyn_cast<TagType>(T))
1236 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1237 if (const TemplateSpecializationType *TST
1238 = dyn_cast<TemplateSpecializationType>(T))
1239 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1240 break;
1241 }
1242
1243 case NestedNameSpecifier::TypeSpecWithTemplate:
1244 case NestedNameSpecifier::Global:
1245 case NestedNameSpecifier::Identifier:
1246 break;
1247 }
1248
1249 return false;
1250}
1251
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001252bool
1253CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1254 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1255 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1256 Qualifiers.push_back(Qualifier);
1257
1258 while (!Qualifiers.empty()) {
1259 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1260 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1261 switch (NNS->getKind()) {
1262 case NestedNameSpecifier::Namespace:
1263 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregor14454802011-02-25 02:25:35 +00001264 Q.getLocalBeginLoc(),
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001265 TU)))
1266 return true;
1267
1268 break;
1269
1270 case NestedNameSpecifier::NamespaceAlias:
1271 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Douglas Gregor14454802011-02-25 02:25:35 +00001272 Q.getLocalBeginLoc(),
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001273 TU)))
1274 return true;
1275
1276 break;
1277
1278 case NestedNameSpecifier::TypeSpec:
1279 case NestedNameSpecifier::TypeSpecWithTemplate:
1280 if (Visit(Q.getTypeLoc()))
1281 return true;
1282
1283 break;
1284
1285 case NestedNameSpecifier::Global:
1286 case NestedNameSpecifier::Identifier:
1287 break;
1288 }
1289 }
1290
1291 return false;
1292}
1293
Douglas Gregor713602b2010-08-31 17:01:39 +00001294bool CursorVisitor::VisitTemplateParameters(
1295 const TemplateParameterList *Params) {
1296 if (!Params)
1297 return false;
1298
1299 for (TemplateParameterList::const_iterator P = Params->begin(),
1300 PEnd = Params->end();
1301 P != PEnd; ++P) {
1302 if (Visit(MakeCXCursor(*P, TU)))
1303 return true;
1304 }
1305
1306 return false;
1307}
1308
Douglas Gregora23e8f72010-08-31 20:37:03 +00001309bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1310 switch (Name.getKind()) {
1311 case TemplateName::Template:
1312 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1313
1314 case TemplateName::OverloadedTemplate:
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001315 // Visit the overloaded template set.
1316 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1317 return true;
1318
Douglas Gregora23e8f72010-08-31 20:37:03 +00001319 return false;
1320
1321 case TemplateName::DependentTemplate:
1322 // FIXME: Visit nested-name-specifier.
1323 return false;
1324
1325 case TemplateName::QualifiedTemplate:
1326 // FIXME: Visit nested-name-specifier.
1327 return Visit(MakeCursorTemplateRef(
1328 Name.getAsQualifiedTemplateName()->getDecl(),
1329 Loc, TU));
Douglas Gregor5590be02011-01-15 06:45:20 +00001330
1331 case TemplateName::SubstTemplateTemplateParmPack:
1332 return Visit(MakeCursorTemplateRef(
1333 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1334 Loc, TU));
Douglas Gregora23e8f72010-08-31 20:37:03 +00001335 }
1336
1337 return false;
1338}
1339
Douglas Gregor713602b2010-08-31 17:01:39 +00001340bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1341 switch (TAL.getArgument().getKind()) {
1342 case TemplateArgument::Null:
1343 case TemplateArgument::Integral:
Douglas Gregor0192c232010-12-20 16:52:59 +00001344 case TemplateArgument::Pack:
Douglas Gregor713602b2010-08-31 17:01:39 +00001345 return false;
1346
Douglas Gregor713602b2010-08-31 17:01:39 +00001347 case TemplateArgument::Type:
1348 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1349 return Visit(TSInfo->getTypeLoc());
1350 return false;
1351
1352 case TemplateArgument::Declaration:
1353 if (Expr *E = TAL.getSourceDeclExpression())
1354 return Visit(MakeCXCursor(E, StmtParent, TU));
1355 return false;
1356
1357 case TemplateArgument::Expression:
1358 if (Expr *E = TAL.getSourceExpression())
1359 return Visit(MakeCXCursor(E, StmtParent, TU));
1360 return false;
1361
1362 case TemplateArgument::Template:
Douglas Gregore4ff4b52011-01-05 18:58:31 +00001363 case TemplateArgument::TemplateExpansion:
Douglas Gregor9d802122011-03-02 17:09:35 +00001364 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1365 return true;
1366
Douglas Gregore4ff4b52011-01-05 18:58:31 +00001367 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregora23e8f72010-08-31 20:37:03 +00001368 TAL.getTemplateNameLoc());
Douglas Gregor713602b2010-08-31 17:01:39 +00001369 }
1370
1371 return false;
1372}
1373
Ted Kremenekb80cba52010-05-07 01:04:29 +00001374bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1375 return VisitDeclContext(D);
1376}
1377
Douglas Gregor12bca222010-08-31 14:41:23 +00001378bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1379 return Visit(TL.getUnqualifiedLoc());
1380}
1381
Douglas Gregord1824312010-01-21 17:29:07 +00001382bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremenek91554282010-11-16 08:15:36 +00001383 ASTContext &Context = AU->getASTContext();
Douglas Gregord1824312010-01-21 17:29:07 +00001384
1385 // Some builtin types (such as Objective-C's "id", "sel", and
1386 // "Class") have associated declarations. Create cursors for those.
1387 QualType VisitType;
1388 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001389 case BuiltinType::Void:
Douglas Gregord1824312010-01-21 17:29:07 +00001390 case BuiltinType::Bool:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001391 case BuiltinType::Char_U:
1392 case BuiltinType::UChar:
Douglas Gregord1824312010-01-21 17:29:07 +00001393 case BuiltinType::Char16:
1394 case BuiltinType::Char32:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001395 case BuiltinType::UShort:
Douglas Gregord1824312010-01-21 17:29:07 +00001396 case BuiltinType::UInt:
1397 case BuiltinType::ULong:
1398 case BuiltinType::ULongLong:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001399 case BuiltinType::UInt128:
1400 case BuiltinType::Char_S:
1401 case BuiltinType::SChar:
Chris Lattnerad3467e2010-12-25 23:25:43 +00001402 case BuiltinType::WChar_U:
1403 case BuiltinType::WChar_S:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001404 case BuiltinType::Short:
1405 case BuiltinType::Int:
1406 case BuiltinType::Long:
1407 case BuiltinType::LongLong:
1408 case BuiltinType::Int128:
1409 case BuiltinType::Float:
1410 case BuiltinType::Double:
1411 case BuiltinType::LongDouble:
1412 case BuiltinType::NullPtr:
1413 case BuiltinType::Overload:
1414 case BuiltinType::Dependent:
John McCall31996342011-04-07 08:22:57 +00001415 case BuiltinType::UnknownAny:
Douglas Gregord1824312010-01-21 17:29:07 +00001416 break;
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001417
Ted Kremenekfcb3db72010-02-18 18:52:18 +00001418 case BuiltinType::ObjCId:
1419 VisitType = Context.getObjCIdType();
1420 break;
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001421
1422 case BuiltinType::ObjCClass:
1423 VisitType = Context.getObjCClassType();
1424 break;
1425
Douglas Gregord1824312010-01-21 17:29:07 +00001426 case BuiltinType::ObjCSel:
1427 VisitType = Context.getObjCSelType();
1428 break;
1429 }
1430
1431 if (!VisitType.isNull()) {
1432 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf441baf2010-02-17 00:41:40 +00001433 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregord1824312010-01-21 17:29:07 +00001434 TU));
1435 }
1436
1437 return false;
1438}
1439
Douglas Gregor93f89952010-01-21 16:28:34 +00001440bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
Richard Smithdda56e42011-04-15 14:24:37 +00001441 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
Douglas Gregor93f89952010-01-21 16:28:34 +00001442}
1443
Douglas Gregord1824312010-01-21 17:29:07 +00001444bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1445 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1446}
1447
1448bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1449 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1450}
1451
Douglas Gregor713602b2010-08-31 17:01:39 +00001452bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001453 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregor713602b2010-08-31 17:01:39 +00001454 // no context information with which we can match up the depth/index in the
1455 // type to the appropriate
1456 return false;
1457}
1458
Douglas Gregord1824312010-01-21 17:29:07 +00001459bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1460 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1461 return true;
1462
John McCall8b07ec22010-05-15 11:32:37 +00001463 return false;
1464}
1465
1466bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1467 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1468 return true;
1469
Douglas Gregord1824312010-01-21 17:29:07 +00001470 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1471 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1472 TU)))
1473 return true;
1474 }
1475
1476 return false;
1477}
1478
1479bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCall8b07ec22010-05-15 11:32:37 +00001480 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001481}
1482
Abramo Bagnara924a8f32010-12-10 16:29:40 +00001483bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1484 return Visit(TL.getInnerLoc());
1485}
1486
Douglas Gregord1824312010-01-21 17:29:07 +00001487bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1488 return Visit(TL.getPointeeLoc());
1489}
1490
1491bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1492 return Visit(TL.getPointeeLoc());
1493}
1494
1495bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00001500 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001501}
1502
1503bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00001504 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001505}
1506
Douglas Gregor12bca222010-08-31 14:41:23 +00001507bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1508 bool SkipResultType) {
1509 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregord1824312010-01-21 17:29:07 +00001510 return true;
1511
Douglas Gregord1824312010-01-21 17:29:07 +00001512 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek6ca136a2010-04-07 00:27:13 +00001513 if (Decl *D = TL.getArg(I))
1514 if (Visit(MakeCXCursor(D, TU)))
1515 return true;
Douglas Gregord1824312010-01-21 17:29:07 +00001516
1517 return false;
1518}
1519
1520bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1521 if (Visit(TL.getElementLoc()))
1522 return true;
1523
1524 if (Expr *Size = TL.getSizeExpr())
1525 return Visit(MakeCXCursor(Size, StmtParent, TU));
1526
1527 return false;
1528}
1529
Douglas Gregor713602b2010-08-31 17:01:39 +00001530bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1531 TemplateSpecializationTypeLoc TL) {
Douglas Gregora23e8f72010-08-31 20:37:03 +00001532 // Visit the template name.
1533 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1534 TL.getTemplateNameLoc()))
1535 return true;
Douglas Gregor713602b2010-08-31 17:01:39 +00001536
1537 // Visit the template arguments.
1538 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1539 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1540 return true;
1541
1542 return false;
1543}
1544
Douglas Gregor6479fc42010-01-21 20:48:56 +00001545bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1546 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1547}
1548
1549bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1550 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1551 return Visit(TSInfo->getTypeLoc());
1552
1553 return false;
1554}
1555
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00001556bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1557 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1558 return true;
1559
1560 return false;
1561}
1562
Douglas Gregora7a795b2011-03-01 20:11:18 +00001563bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1564 DependentTemplateSpecializationTypeLoc TL) {
1565 // Visit the nested-name-specifier, if there is one.
1566 if (TL.getQualifierLoc() &&
1567 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1568 return true;
1569
1570 // Visit the template arguments.
1571 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1572 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1573 return true;
1574
1575 return false;
1576}
1577
Douglas Gregor844cb502011-03-01 18:12:44 +00001578bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1579 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1580 return true;
1581
1582 return Visit(TL.getNamedTypeLoc());
1583}
1584
Douglas Gregord2fa7662010-12-20 02:24:11 +00001585bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1586 return Visit(TL.getPatternLoc());
1587}
1588
Ted Kremenekae9e2212010-08-27 21:34:58 +00001589bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregor14454802011-02-25 02:25:35 +00001590 // Visit the nested-name-specifier, if present.
1591 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1592 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1593 return true;
1594
Ted Kremenekae9e2212010-08-27 21:34:58 +00001595 if (D->isDefinition()) {
1596 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1597 E = D->bases_end(); I != E; ++I) {
1598 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1599 return true;
1600 }
1601 }
1602
1603 return VisitTagDecl(D);
1604}
1605
Ted Kremenek6ab9aa022010-02-18 05:46:33 +00001606bool CursorVisitor::VisitAttributes(Decl *D) {
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001607 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1608 i != e; ++i)
1609 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek6ab9aa022010-02-18 05:46:33 +00001610 return true;
1611
1612 return false;
1613}
1614
Ted Kremenek92209a42010-11-11 08:05:18 +00001615//===----------------------------------------------------------------------===//
1616// Data-recursive visitor methods.
1617//===----------------------------------------------------------------------===//
1618
Ted Kremenekacff73c2010-11-13 00:36:47 +00001619namespace {
Ted Kremenek072e6372010-11-13 00:36:50 +00001620#define DEF_JOB(NAME, DATA, KIND)\
1621class NAME : public VisitorJob {\
1622public:\
1623 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1624 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenek83900272010-11-18 00:02:32 +00001625 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek072e6372010-11-13 00:36:50 +00001626};
1627
1628DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1629DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremenek573411b2010-11-13 00:58:18 +00001630DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek072e6372010-11-13 00:36:50 +00001631DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001632DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1633 ExplicitTemplateArgsVisitKind)
Douglas Gregor557f05c2011-01-19 20:34:17 +00001634DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek072e6372010-11-13 00:36:50 +00001635#undef DEF_JOB
1636
1637class DeclVisit : public VisitorJob {
1638public:
1639 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1640 VisitorJob(parent, VisitorJob::DeclVisitKind,
1641 d, isFirst ? (void*) 1 : (void*) 0) {}
1642 static bool classof(const VisitorJob *VJ) {
Ted Kremeneke6f03042010-11-15 22:23:26 +00001643 return VJ->getKind() == DeclVisitKind;
Ted Kremenek072e6372010-11-13 00:36:50 +00001644 }
Ted Kremenek83900272010-11-18 00:02:32 +00001645 Decl *get() const { return static_cast<Decl*>(data[0]); }
1646 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek072e6372010-11-13 00:36:50 +00001647};
Ted Kremenek072e6372010-11-13 00:36:50 +00001648class TypeLocVisit : public VisitorJob {
1649public:
1650 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1651 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1652 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1653
1654 static bool classof(const VisitorJob *VJ) {
1655 return VJ->getKind() == TypeLocVisitKind;
1656 }
1657
Ted Kremeneke6f03042010-11-15 22:23:26 +00001658 TypeLoc get() const {
Ted Kremenek83900272010-11-18 00:02:32 +00001659 QualType T = QualType::getFromOpaquePtr(data[0]);
1660 return TypeLoc(T, data[1]);
Ted Kremenek072e6372010-11-13 00:36:50 +00001661 }
1662};
1663
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001664class LabelRefVisit : public VisitorJob {
1665public:
Chris Lattnerc8e630e2011-02-17 07:39:24 +00001666 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1667 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001668 labelLoc.getPtrEncoding()) {}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001669
1670 static bool classof(const VisitorJob *VJ) {
1671 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1672 }
Chris Lattnerc8e630e2011-02-17 07:39:24 +00001673 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001674 SourceLocation getLoc() const {
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001675 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenek83900272010-11-18 00:02:32 +00001676};
1677class NestedNameSpecifierVisit : public VisitorJob {
1678public:
1679 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1680 CXCursor parent)
1681 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001682 NS, R.getBegin().getPtrEncoding(),
1683 R.getEnd().getPtrEncoding()) {}
Ted Kremenek83900272010-11-18 00:02:32 +00001684 static bool classof(const VisitorJob *VJ) {
1685 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1686 }
1687 NestedNameSpecifier *get() const {
1688 return static_cast<NestedNameSpecifier*>(data[0]);
1689 }
1690 SourceRange getSourceRange() const {
1691 SourceLocation A =
1692 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1693 SourceLocation B =
1694 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1695 return SourceRange(A, B);
1696 }
1697};
Douglas Gregora6ce6082011-02-25 18:19:59 +00001698
1699class NestedNameSpecifierLocVisit : public VisitorJob {
1700public:
1701 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1702 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1703 Qualifier.getNestedNameSpecifier(),
1704 Qualifier.getOpaqueData()) { }
1705
1706 static bool classof(const VisitorJob *VJ) {
1707 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1708 }
1709
1710 NestedNameSpecifierLoc get() const {
1711 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1712 data[1]);
1713 }
1714};
1715
Ted Kremenek83900272010-11-18 00:02:32 +00001716class DeclarationNameInfoVisit : public VisitorJob {
1717public:
1718 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1719 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1720 static bool classof(const VisitorJob *VJ) {
1721 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1722 }
1723 DeclarationNameInfo get() const {
1724 Stmt *S = static_cast<Stmt*>(data[0]);
1725 switch (S->getStmtClass()) {
1726 default:
1727 llvm_unreachable("Unhandled Stmt");
1728 case Stmt::CXXDependentScopeMemberExprClass:
1729 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1730 case Stmt::DependentScopeDeclRefExprClass:
1731 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1732 }
1733 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001734};
Ted Kremenek5d304a32010-11-18 00:42:18 +00001735class MemberRefVisit : public VisitorJob {
1736public:
1737 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1738 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001739 L.getPtrEncoding()) {}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1742 }
1743 FieldDecl *get() const {
1744 return static_cast<FieldDecl*>(data[0]);
1745 }
1746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1748 }
1749};
Ted Kremenekacff73c2010-11-13 00:36:47 +00001750class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1751 VisitorWorkList &WL;
1752 CXCursor Parent;
1753public:
1754 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1755 : WL(wl), Parent(parent) {}
1756
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001757 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001758 void VisitBlockExpr(BlockExpr *B);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001759 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenekfdc52372010-11-13 05:38:03 +00001760 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001761 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenek83900272010-11-18 00:02:32 +00001762 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001763 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek9f49b372010-11-17 02:18:35 +00001764 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001765 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001766 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001767 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremeneka51cc432010-11-17 00:50:41 +00001768 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek79ddc672010-11-17 00:50:36 +00001769 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek7003a502010-11-17 00:50:52 +00001770 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremenek573411b2010-11-13 00:58:18 +00001771 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek072e6372010-11-13 00:36:50 +00001772 void VisitDeclStmt(DeclStmt *S);
Ted Kremenek83900272010-11-18 00:02:32 +00001773 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001774 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001775 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1776 void VisitForStmt(ForStmt *FS);
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001777 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001778 void VisitIfStmt(IfStmt *If);
1779 void VisitInitListExpr(InitListExpr *IE);
1780 void VisitMemberExpr(MemberExpr *M);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001781 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001782 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001783 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1784 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournee190dee2011-03-11 19:24:49 +00001785 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001786 void VisitStmt(Stmt *S);
1787 void VisitSwitchStmt(SwitchStmt *S);
1788 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek513cd572010-11-17 00:50:50 +00001789 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00001790 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001791 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenekc1c30cd2010-11-17 00:50:43 +00001792 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor557f05c2011-01-19 20:34:17 +00001793 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregor820ba7b2011-01-04 17:33:58 +00001794
Ted Kremenekacff73c2010-11-13 00:36:47 +00001795private:
Ted Kremenek83900272010-11-18 00:02:32 +00001796 void AddDeclarationNameInfo(Stmt *S);
1797 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregora6ce6082011-02-25 18:19:59 +00001798 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001799 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001800 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001801 void AddStmt(Stmt *S);
Ted Kremenek072e6372010-11-13 00:36:50 +00001802 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001803 void AddTypeLoc(TypeSourceInfo *TI);
1804 void EnqueueChildren(Stmt *S);
1805};
1806} // end anonyous namespace
1807
Ted Kremenek83900272010-11-18 00:02:32 +00001808void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1809 // 'S' should always be non-null, since it comes from the
1810 // statement we are visiting.
1811 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1812}
1813void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1814 SourceRange R) {
1815 if (N)
1816 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1817}
Douglas Gregora6ce6082011-02-25 18:19:59 +00001818
1819void
1820EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1821 if (Qualifier)
1822 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1823}
1824
Ted Kremenekacff73c2010-11-13 00:36:47 +00001825void EnqueueVisitor::AddStmt(Stmt *S) {
1826 if (S)
1827 WL.push_back(StmtVisit(S, Parent));
1828}
Ted Kremenek072e6372010-11-13 00:36:50 +00001829void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00001830 if (D)
Ted Kremenek072e6372010-11-13 00:36:50 +00001831 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenekacff73c2010-11-13 00:36:47 +00001832}
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001833void EnqueueVisitor::
1834 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1835 if (A)
1836 WL.push_back(ExplicitTemplateArgsVisit(
1837 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1838}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001839void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1840 if (D)
1841 WL.push_back(MemberRefVisit(D, L, Parent));
1842}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001843void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1844 if (TI)
1845 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1846 }
1847void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremenek6a5df572010-11-12 21:34:09 +00001848 unsigned size = WL.size();
John McCall8322c3a2011-02-13 04:07:26 +00001849 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00001850 AddStmt(*Child);
Ted Kremenek6a5df572010-11-12 21:34:09 +00001851 }
1852 if (size == WL.size())
1853 return;
1854 // Now reverse the entries we just added. This will match the DFS
1855 // ordering performed by the worklist.
1856 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1857 std::reverse(I, E);
1858}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001859void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1860 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1861}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001862void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1863 AddDecl(B->getBlockDecl());
1864}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001865void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1866 EnqueueChildren(E);
1867 AddTypeLoc(E->getTypeSourceInfo());
1868}
Ted Kremenekfdc52372010-11-13 05:38:03 +00001869void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1870 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1871 E = S->body_rend(); I != E; ++I) {
1872 AddStmt(*I);
1873 }
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001874}
Ted Kremenek83900272010-11-18 00:02:32 +00001875void EnqueueVisitor::
1876VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1877 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1878 AddDeclarationNameInfo(E);
Douglas Gregore16af532011-02-28 18:50:33 +00001879 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1880 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenek83900272010-11-18 00:02:32 +00001881 if (!E->isImplicitAccess())
1882 AddStmt(E->getBase());
1883}
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001884void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1885 // Enqueue the initializer or constructor arguments.
1886 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1887 AddStmt(E->getConstructorArg(I-1));
1888 // Enqueue the array size, if any.
1889 AddStmt(E->getArraySize());
1890 // Enqueue the allocated type.
1891 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1892 // Enqueue the placement arguments.
1893 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1894 AddStmt(E->getPlacementArg(I-1));
1895}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001896void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenekbc8b3782010-11-13 05:55:56 +00001897 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1898 AddStmt(CE->getArg(I-1));
Ted Kremenekacff73c2010-11-13 00:36:47 +00001899 AddStmt(CE->getCallee());
1900 AddStmt(CE->getArg(0));
1901}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001902void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1903 // Visit the name of the type being destroyed.
1904 AddTypeLoc(E->getDestroyedTypeInfo());
1905 // Visit the scope type that looks disturbingly like the nested-name-specifier
1906 // but isn't.
1907 AddTypeLoc(E->getScopeTypeInfo());
1908 // Visit the nested-name-specifier.
Douglas Gregora6ce6082011-02-25 18:19:59 +00001909 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1910 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001911 // Visit base expression.
1912 AddStmt(E->getBase());
1913}
Ted Kremenek9f49b372010-11-17 02:18:35 +00001914void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1915 AddTypeLoc(E->getTypeSourceInfo());
1916}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001917void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1918 EnqueueChildren(E);
1919 AddTypeLoc(E->getTypeSourceInfo());
1920}
Ted Kremeneka51cc432010-11-17 00:50:41 +00001921void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1922 EnqueueChildren(E);
1923 if (E->isTypeOperand())
1924 AddTypeLoc(E->getTypeOperandSourceInfo());
1925}
Ted Kremenek79ddc672010-11-17 00:50:36 +00001926
1927void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1928 *E) {
1929 EnqueueChildren(E);
1930 AddTypeLoc(E->getTypeSourceInfo());
1931}
Ted Kremenek7003a502010-11-17 00:50:52 +00001932void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1933 EnqueueChildren(E);
1934 if (E->isTypeOperand())
1935 AddTypeLoc(E->getTypeOperandSourceInfo());
1936}
Ted Kremenek573411b2010-11-13 00:58:18 +00001937void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001938 if (DR->hasExplicitTemplateArgs()) {
1939 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1940 }
Ted Kremenek573411b2010-11-13 00:58:18 +00001941 WL.push_back(DeclRefExprParts(DR, Parent));
1942}
Ted Kremenek83900272010-11-18 00:02:32 +00001943void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1944 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1945 AddDeclarationNameInfo(E);
Douglas Gregor3a43fd62011-02-25 20:49:16 +00001946 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenek83900272010-11-18 00:02:32 +00001947}
Ted Kremenek072e6372010-11-13 00:36:50 +00001948void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1949 unsigned size = WL.size();
1950 bool isFirst = true;
1951 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1952 D != DEnd; ++D) {
1953 AddDecl(*D, isFirst);
1954 isFirst = false;
1955 }
1956 if (size == WL.size())
1957 return;
1958 // Now reverse the entries we just added. This will match the DFS
1959 // ordering performed by the worklist.
1960 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1961 std::reverse(I, E);
1962}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001963void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1964 AddStmt(E->getInit());
1965 typedef DesignatedInitExpr::Designator Designator;
1966 for (DesignatedInitExpr::reverse_designators_iterator
1967 D = E->designators_rbegin(), DEnd = E->designators_rend();
1968 D != DEnd; ++D) {
1969 if (D->isFieldDesignator()) {
1970 if (FieldDecl *Field = D->getField())
1971 AddMemberRef(Field, D->getFieldLoc());
1972 continue;
1973 }
1974 if (D->isArrayDesignator()) {
1975 AddStmt(E->getArrayIndex(*D));
1976 continue;
1977 }
1978 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1979 AddStmt(E->getArrayRangeEnd(*D));
1980 AddStmt(E->getArrayRangeStart(*D));
1981 }
1982}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001983void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1984 EnqueueChildren(E);
1985 AddTypeLoc(E->getTypeInfoAsWritten());
1986}
1987void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1988 AddStmt(FS->getBody());
1989 AddStmt(FS->getInc());
1990 AddStmt(FS->getCond());
1991 AddDecl(FS->getConditionVariable());
1992 AddStmt(FS->getInit());
1993}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001994void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1995 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1996}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001997void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
1998 AddStmt(If->getElse());
1999 AddStmt(If->getThen());
2000 AddStmt(If->getCond());
2001 AddDecl(If->getConditionVariable());
2002}
2003void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
2004 // We care about the syntactic form of the initializer list, only.
2005 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2006 IE = Syntactic;
2007 EnqueueChildren(IE);
2008}
2009void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor30313cb2010-11-17 17:15:08 +00002010 WL.push_back(MemberExprParts(M, Parent));
2011
2012 // If the base of the member access expression is an implicit 'this', don't
2013 // visit it.
2014 // FIXME: If we ever want to show these implicit accesses, this will be
2015 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor25b7e052011-03-02 21:06:53 +00002016 if (!M->isImplicitAccess())
2017 AddStmt(M->getBase());
Ted Kremenekacff73c2010-11-13 00:36:47 +00002018}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00002019void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2020 AddTypeLoc(E->getEncodedTypeSourceInfo());
2021}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002022void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2023 EnqueueChildren(M);
2024 AddTypeLoc(M->getClassReceiverTypeInfo());
2025}
Ted Kremenek5d304a32010-11-18 00:42:18 +00002026void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2027 // Visit the components of the offsetof expression.
2028 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2029 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2030 const OffsetOfNode &Node = E->getComponent(I-1);
2031 switch (Node.getKind()) {
2032 case OffsetOfNode::Array:
2033 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2034 break;
2035 case OffsetOfNode::Field:
Abramo Bagnara6b6f0512011-03-12 09:45:03 +00002036 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenek5d304a32010-11-18 00:42:18 +00002037 break;
2038 case OffsetOfNode::Identifier:
2039 case OffsetOfNode::Base:
2040 continue;
2041 }
2042 }
2043 // Visit the type into which we're computing the offset.
2044 AddTypeLoc(E->getTypeSourceInfo());
2045}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002046void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek8eaa1652010-11-17 00:50:47 +00002047 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002048 WL.push_back(OverloadExprParts(E, Parent));
2049}
Peter Collingbournee190dee2011-03-11 19:24:49 +00002050void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2051 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek9f49b372010-11-17 02:18:35 +00002052 EnqueueChildren(E);
2053 if (E->isArgumentType())
2054 AddTypeLoc(E->getArgumentTypeInfo());
2055}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002056void EnqueueVisitor::VisitStmt(Stmt *S) {
2057 EnqueueChildren(S);
2058}
2059void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2060 AddStmt(S->getBody());
2061 AddStmt(S->getCond());
2062 AddDecl(S->getConditionVariable());
2063}
Ted Kremenekdd0d4b42010-11-17 00:50:39 +00002064
Ted Kremenekacff73c2010-11-13 00:36:47 +00002065void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2066 AddStmt(W->getBody());
2067 AddStmt(W->getCond());
2068 AddDecl(W->getConditionVariable());
2069}
Ted Kremenek513cd572010-11-17 00:50:50 +00002070void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2071 AddTypeLoc(E->getQueriedTypeSourceInfo());
2072}
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002073
2074void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002075 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichetcf7731b2010-12-08 09:11:05 +00002076 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002077}
2078
Ted Kremenekacff73c2010-11-13 00:36:47 +00002079void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2080 VisitOverloadExpr(U);
2081 if (!U->isImplicitAccess())
2082 AddStmt(U->getBase());
2083}
Ted Kremenekc1c30cd2010-11-17 00:50:43 +00002084void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2085 AddStmt(E->getSubExpr());
2086 AddTypeLoc(E->getWrittenTypeInfo());
2087}
Douglas Gregor557f05c2011-01-19 20:34:17 +00002088void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2089 WL.push_back(SizeOfPackExprParts(E, Parent));
2090}
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002091
Ted Kremenek92209a42010-11-11 08:05:18 +00002092void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00002093 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenek92209a42010-11-11 08:05:18 +00002094}
2095
2096bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2097 if (RegionOfInterest.isValid()) {
2098 SourceRange Range = getRawCursorExtent(C);
2099 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2100 return false;
2101 }
2102 return true;
2103}
2104
2105bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2106 while (!WL.empty()) {
2107 // Dequeue the worklist item.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002108 VisitorJob LI = WL.back();
2109 WL.pop_back();
2110
Ted Kremenek92209a42010-11-11 08:05:18 +00002111 // Set the Parent field, then back to its old value once we're done.
2112 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2113
2114 switch (LI.getKind()) {
Ted Kremenek73227d72010-11-12 18:26:56 +00002115 case VisitorJob::DeclVisitKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002116 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenek73227d72010-11-12 18:26:56 +00002117 if (!D)
2118 continue;
2119
2120 // For now, perform default visitation for Decls.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002121 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenek73227d72010-11-12 18:26:56 +00002122 return true;
2123
2124 continue;
2125 }
Ted Kremenek8eaa1652010-11-17 00:50:47 +00002126 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2127 const ExplicitTemplateArgumentList *ArgList =
2128 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2129 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2130 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2131 Arg != ArgEnd; ++Arg) {
2132 if (VisitTemplateArgumentLoc(*Arg))
2133 return true;
2134 }
2135 continue;
2136 }
Ted Kremeneke12bcf52010-11-12 21:34:12 +00002137 case VisitorJob::TypeLocVisitKind: {
2138 // Perform default visitation for TypeLocs.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002139 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremeneke12bcf52010-11-12 21:34:12 +00002140 return true;
2141 continue;
2142 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00002143 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerc8e630e2011-02-17 07:39:24 +00002144 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremenekc49211c2011-02-23 04:54:51 +00002145 if (LabelStmt *stmt = LS->getStmt()) {
2146 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2147 TU))) {
2148 return true;
2149 }
2150 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00002151 continue;
2152 }
Douglas Gregora6ce6082011-02-25 18:19:59 +00002153
Ted Kremenek83900272010-11-18 00:02:32 +00002154 case VisitorJob::NestedNameSpecifierVisitKind: {
2155 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2156 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2157 return true;
2158 continue;
2159 }
Douglas Gregora6ce6082011-02-25 18:19:59 +00002160
2161 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2162 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2163 if (VisitNestedNameSpecifierLoc(V->get()))
2164 return true;
2165 continue;
2166 }
2167
Ted Kremenek83900272010-11-18 00:02:32 +00002168 case VisitorJob::DeclarationNameInfoVisitKind: {
2169 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2170 ->get()))
2171 return true;
2172 continue;
2173 }
Ted Kremenek5d304a32010-11-18 00:42:18 +00002174 case VisitorJob::MemberRefVisitKind: {
2175 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2176 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2177 return true;
2178 continue;
2179 }
Ted Kremenek92209a42010-11-11 08:05:18 +00002180 case VisitorJob::StmtVisitKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002181 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek7716cd62010-11-11 23:11:43 +00002182 if (!S)
2183 continue;
2184
Ted Kremenek73227d72010-11-12 18:26:56 +00002185 // Update the current cursor.
Ted Kremenek92209a42010-11-11 08:05:18 +00002186 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenek5d304a32010-11-18 00:42:18 +00002187 if (!IsInRegionOfInterest(Cursor))
2188 continue;
2189 switch (Visitor(Cursor, Parent, ClientData)) {
2190 case CXChildVisit_Break: return true;
2191 case CXChildVisit_Continue: break;
2192 case CXChildVisit_Recurse:
2193 EnqueueWorkList(WL, S);
Ted Kremeneke6f03042010-11-15 22:23:26 +00002194 break;
Ted Kremenek92209a42010-11-11 08:05:18 +00002195 }
Ted Kremeneke6f03042010-11-15 22:23:26 +00002196 continue;
Ted Kremenek92209a42010-11-11 08:05:18 +00002197 }
2198 case VisitorJob::MemberExprPartsKind: {
2199 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002200 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenek92209a42010-11-11 08:05:18 +00002201
2202 // Visit the nested-name-specifier
Douglas Gregorea972d32011-02-28 21:54:11 +00002203 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2204 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek92209a42010-11-11 08:05:18 +00002205 return true;
2206
2207 // Visit the declaration name.
2208 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2209 return true;
2210
2211 // Visit the explicitly-specified template arguments, if any.
2212 if (M->hasExplicitTemplateArgs()) {
2213 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2214 *ArgEnd = Arg + M->getNumTemplateArgs();
2215 Arg != ArgEnd; ++Arg) {
2216 if (VisitTemplateArgumentLoc(*Arg))
2217 return true;
2218 }
2219 }
2220 continue;
2221 }
Ted Kremenek573411b2010-11-13 00:58:18 +00002222 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002223 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremenek573411b2010-11-13 00:58:18 +00002224 // Visit nested-name-specifier, if present.
Douglas Gregorea972d32011-02-28 21:54:11 +00002225 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2226 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek573411b2010-11-13 00:58:18 +00002227 return true;
2228 // Visit declaration name.
2229 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2230 return true;
Ted Kremenek573411b2010-11-13 00:58:18 +00002231 continue;
2232 }
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002233 case VisitorJob::OverloadExprPartsKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002234 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002235 // Visit the nested-name-specifier.
Douglas Gregor0da1d432011-02-28 20:01:57 +00002236 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2237 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002238 return true;
2239 // Visit the declaration name.
2240 if (VisitDeclarationNameInfo(O->getNameInfo()))
2241 return true;
2242 // Visit the overloaded declaration reference.
2243 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2244 return true;
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002245 continue;
2246 }
Douglas Gregor557f05c2011-01-19 20:34:17 +00002247 case VisitorJob::SizeOfPackExprPartsKind: {
2248 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2249 NamedDecl *Pack = E->getPack();
2250 if (isa<TemplateTypeParmDecl>(Pack)) {
2251 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2252 E->getPackLoc(), TU)))
2253 return true;
2254
2255 continue;
2256 }
2257
2258 if (isa<TemplateTemplateParmDecl>(Pack)) {
2259 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2260 E->getPackLoc(), TU)))
2261 return true;
2262
2263 continue;
2264 }
2265
2266 // Non-type template parameter packs and function parameter packs are
2267 // treated like DeclRefExpr cursors.
2268 continue;
2269 }
Ted Kremenek92209a42010-11-11 08:05:18 +00002270 }
2271 }
2272 return false;
2273}
2274
Ted Kremenek5d304a32010-11-18 00:42:18 +00002275bool CursorVisitor::Visit(Stmt *S) {
Ted Kremeneka4c27ec2010-11-15 23:31:32 +00002276 VisitorWorkList *WL = 0;
2277 if (!WorkListFreeList.empty()) {
2278 WL = WorkListFreeList.back();
2279 WL->clear();
2280 WorkListFreeList.pop_back();
2281 }
2282 else {
2283 WL = new VisitorWorkList();
2284 WorkListCache.push_back(WL);
2285 }
2286 EnqueueWorkList(*WL, S);
2287 bool result = RunVisitorWorkList(*WL);
2288 WorkListFreeList.push_back(WL);
2289 return result;
Ted Kremenek92209a42010-11-11 08:05:18 +00002290}
2291
2292//===----------------------------------------------------------------------===//
2293// Misc. API hooks.
2294//===----------------------------------------------------------------------===//
2295
Douglas Gregor2c844822010-09-24 21:18:36 +00002296static llvm::sys::Mutex EnableMultithreadingMutex;
2297static bool EnabledMultithreading;
2298
Benjamin Kramer61f5d0c2009-10-18 16:11:04 +00002299extern "C" {
Douglas Gregor1e21cc72010-02-18 23:07:20 +00002300CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2301 int displayDiagnostics) {
Daniel Dunbara5af410d2010-10-08 19:30:33 +00002302 // Disable pretty stack trace functionality, which will otherwise be a very
2303 // poor citizen of the world and set up all sorts of signal handlers.
2304 llvm::DisablePrettyStackTrace = true;
2305
Daniel Dunbarc91f2ff2010-08-18 18:43:14 +00002306 // We use crash recovery to make some of our APIs more reliable, implicitly
2307 // enable it.
2308 llvm::CrashRecoveryContext::Enable();
2309
Douglas Gregor2c844822010-09-24 21:18:36 +00002310 // Enable support for multithreading in LLVM.
2311 {
2312 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2313 if (!EnabledMultithreading) {
2314 llvm::llvm_start_multithreaded();
2315 EnabledMultithreading = true;
2316 }
2317 }
2318
Douglas Gregor87752492010-01-22 20:35:53 +00002319 CIndexer *CIdxr = new CIndexer();
Steve Naroff531e2842009-10-20 14:46:24 +00002320 if (excludeDeclarationsFromPCH)
2321 CIdxr->setOnlyLocalDecls();
Douglas Gregor1e21cc72010-02-18 23:07:20 +00002322 if (displayDiagnostics)
2323 CIdxr->setDisplayDiagnostics();
Steve Naroff531e2842009-10-20 14:46:24 +00002324 return CIdxr;
Steve Naroffd5e8e862009-08-27 19:51:58 +00002325}
2326
Daniel Dunbar079203f2009-12-01 03:14:51 +00002327void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002328 if (CIdx)
2329 delete static_cast<CIndexer *>(CIdx);
Steve Naroff3aa2d732009-09-17 18:33:27 +00002330}
2331
Ted Kremenek1ec7b332011-03-18 23:05:39 +00002332void clang_toggleCrashRecovery(unsigned isEnabled) {
2333 if (isEnabled)
2334 llvm::CrashRecoveryContext::Enable();
2335 else
2336 llvm::CrashRecoveryContext::Disable();
2337}
2338
Daniel Dunbar079203f2009-12-01 03:14:51 +00002339CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002340 const char *ast_filename) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002341 if (!CIdx)
2342 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002343
Douglas Gregor16bef852009-10-16 20:01:17 +00002344 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis71731d62010-11-03 22:45:23 +00002345 FileSystemOptions FileSystemOpts;
2346 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002347
Douglas Gregor7f95d262010-04-05 23:52:57 +00002348 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremenek91554282010-11-16 08:15:36 +00002349 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002350 CXXIdx->getOnlyLocalDecls(),
2351 0, 0, true);
Ted Kremenek91554282010-11-16 08:15:36 +00002352 return MakeCXTranslationUnit(TU);
Steve Naroffd5e8e862009-08-27 19:51:58 +00002353}
2354
Douglas Gregor4a47bca2010-08-09 22:28:58 +00002355unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor176d2862010-09-27 05:49:58 +00002356 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregorf5a18542010-10-27 17:24:53 +00002357 CXTranslationUnit_CacheCompletionResults |
2358 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregor4a47bca2010-08-09 22:28:58 +00002359}
2360
Daniel Dunbar079203f2009-12-01 03:14:51 +00002361CXTranslationUnit
2362clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2363 const char *source_filename,
2364 int num_command_line_args,
Douglas Gregor57879fa2010-09-01 16:43:19 +00002365 const char * const *command_line_args,
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002366 unsigned num_unsaved_files,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002367 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor99d2cf42010-07-21 18:52:53 +00002368 return clang_parseTranslationUnit(CIdx, source_filename,
2369 command_line_args, num_command_line_args,
2370 unsaved_files, num_unsaved_files,
2371 CXTranslationUnit_DetailedPreprocessingRecord);
2372}
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002373
2374struct ParseTranslationUnitInfo {
2375 CXIndex CIdx;
2376 const char *source_filename;
Douglas Gregor57879fa2010-09-01 16:43:19 +00002377 const char *const *command_line_args;
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002378 int num_command_line_args;
2379 struct CXUnsavedFile *unsaved_files;
2380 unsigned num_unsaved_files;
2381 unsigned options;
2382 CXTranslationUnit result;
2383};
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002384static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002385 ParseTranslationUnitInfo *PTUI =
2386 static_cast<ParseTranslationUnitInfo*>(UserData);
2387 CXIndex CIdx = PTUI->CIdx;
2388 const char *source_filename = PTUI->source_filename;
Douglas Gregor57879fa2010-09-01 16:43:19 +00002389 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002390 int num_command_line_args = PTUI->num_command_line_args;
2391 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2392 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2393 unsigned options = PTUI->options;
2394 PTUI->result = 0;
Douglas Gregor99d2cf42010-07-21 18:52:53 +00002395
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002396 if (!CIdx)
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002397 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002398
Steve Naroff531e2842009-10-20 14:46:24 +00002399 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2400
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002401 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregor028d3e42010-08-09 20:45:32 +00002402 bool CompleteTranslationUnit
2403 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregorb14904c2010-08-13 22:48:40 +00002404 bool CacheCodeCompetionResults
2405 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregorf5a18542010-10-27 17:24:53 +00002406 bool CXXPrecompilePreamble
2407 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2408 bool CXXChainedPCH
2409 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregorb14904c2010-08-13 22:48:40 +00002410
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002411 // Configure the diagnostics.
2412 DiagnosticOptions DiagOpts;
Ted Kremenek022a4902011-03-22 01:15:24 +00002413 llvm::IntrusiveRefCntPtr<Diagnostic>
2414 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2415 command_line_args));
Ted Kremenekf441baf2010-02-17 00:41:40 +00002416
Ted Kremenek022a4902011-03-22 01:15:24 +00002417 // Recover resources if we crash before exiting this function.
2418 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2419 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2420 DiagCleanup(Diags.getPtr());
2421
2422 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2423 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2424
2425 // Recover resources if we crash before exiting this function.
2426 llvm::CrashRecoveryContextCleanupRegistrar<
2427 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2428
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002429 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattner58c79342010-04-05 22:42:27 +00002430 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002431 const llvm::MemoryBuffer *Buffer
Chris Lattner58c79342010-04-05 22:42:27 +00002432 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek022a4902011-03-22 01:15:24 +00002433 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2434 Buffer));
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002435 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00002436
Ted Kremenek022a4902011-03-22 01:15:24 +00002437 llvm::OwningPtr<std::vector<const char *> >
2438 Args(new std::vector<const char*>());
2439
2440 // Recover resources if we crash before exiting this method.
2441 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2442 ArgsCleanup(Args.get());
2443
Douglas Gregor79edde82010-07-09 18:39:07 +00002444 // Since the Clang C library is primarily used by batch tools dealing with
2445 // (often very broken) source code, where spell-checking can have a
2446 // significant negative impact on performance (particularly when
2447 // precompiled headers are involved), we disable it by default.
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002448 // Only do this if we haven't found a spell-checking-related argument.
2449 bool FoundSpellCheckingArgument = false;
2450 for (int I = 0; I != num_command_line_args; ++I) {
2451 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2452 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2453 FoundSpellCheckingArgument = true;
2454 break;
Steve Naroff531e2842009-10-20 14:46:24 +00002455 }
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002456 }
2457 if (!FoundSpellCheckingArgument)
Ted Kremenek022a4902011-03-22 01:15:24 +00002458 Args->push_back("-fno-spell-checking");
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002459
Ted Kremenek022a4902011-03-22 01:15:24 +00002460 Args->insert(Args->end(), command_line_args,
2461 command_line_args + num_command_line_args);
Douglas Gregorac0605e2010-01-28 06:00:51 +00002462
Argyrios Kyrtzidise7620202011-03-20 18:17:52 +00002463 // The 'source_filename' argument is optional. If the caller does not
2464 // specify it then it is assumed that the source file is specified
2465 // in the actual argument list.
2466 // Put the source file after command_line_args otherwise if '-x' flag is
2467 // present it will be unused.
2468 if (source_filename)
Ted Kremenek022a4902011-03-22 01:15:24 +00002469 Args->push_back(source_filename);
Argyrios Kyrtzidise7620202011-03-20 18:17:52 +00002470
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002471 // Do we need the detailed preprocessing record?
2472 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek022a4902011-03-22 01:15:24 +00002473 Args->push_back("-Xclang");
2474 Args->push_back("-detailed-preprocessing-record");
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002475 }
2476
Argyrios Kyrtzidis8d5038c2010-11-18 21:47:04 +00002477 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002478 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek600b54c2011-03-22 20:16:19 +00002479 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2480 /* vector::data() not portable */,
2481 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002482 Diags,
2483 CXXIdx->getClangResourcesPath(),
2484 CXXIdx->getOnlyLocalDecls(),
Douglas Gregor44c6ee72010-11-11 00:39:14 +00002485 /*CaptureDiagnostics=*/true,
Ted Kremenek600b54c2011-03-22 20:16:19 +00002486 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek022a4902011-03-22 01:15:24 +00002487 RemappedFiles->size(),
Argyrios Kyrtzidis97d3a382011-03-08 23:35:24 +00002488 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002489 PrecompilePreamble,
2490 CompleteTranslationUnit,
Douglas Gregorf5a18542010-10-27 17:24:53 +00002491 CacheCodeCompetionResults,
2492 CXXPrecompilePreamble,
2493 CXXChainedPCH));
Ted Kremenekf441baf2010-02-17 00:41:40 +00002494
Argyrios Kyrtzidis8d5038c2010-11-18 21:47:04 +00002495 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002496 // Make sure to check that 'Unit' is non-NULL.
2497 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2498 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2499 DEnd = Unit->stored_diag_end();
2500 D != DEnd; ++D) {
2501 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2502 CXString Msg = clang_formatDiagnostic(&Diag,
2503 clang_defaultDiagnosticDisplayOptions());
2504 fprintf(stderr, "%s\n", clang_getCString(Msg));
2505 clang_disposeString(Msg);
2506 }
Douglas Gregord770f732010-02-22 23:17:23 +00002507#ifdef LLVM_ON_WIN32
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002508 // On Windows, force a flush, since there may be multiple copies of
2509 // stderr and stdout in the file system, all with different buffers
2510 // but writing to the same device.
2511 fflush(stderr);
2512#endif
2513 }
Douglas Gregor33cdd812010-02-18 18:08:43 +00002514 }
Douglas Gregorac0605e2010-01-28 06:00:51 +00002515
Ted Kremenek91554282010-11-16 08:15:36 +00002516 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002517}
2518CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2519 const char *source_filename,
Douglas Gregor57879fa2010-09-01 16:43:19 +00002520 const char * const *command_line_args,
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002521 int num_command_line_args,
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002522 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002523 unsigned num_unsaved_files,
2524 unsigned options) {
2525 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002526 num_command_line_args, unsaved_files,
2527 num_unsaved_files, options, 0 };
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002528 llvm::CrashRecoveryContext CRC;
2529
Daniel Dunbarb7383e62010-11-05 07:19:31 +00002530 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbarf10f9be2010-08-23 22:35:34 +00002531 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2532 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2533 fprintf(stderr, " 'command_line_args' : [");
2534 for (int i = 0; i != num_command_line_args; ++i) {
2535 if (i)
2536 fprintf(stderr, ", ");
2537 fprintf(stderr, "'%s'", command_line_args[i]);
2538 }
2539 fprintf(stderr, "],\n");
2540 fprintf(stderr, " 'unsaved_files' : [");
2541 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2542 if (i)
2543 fprintf(stderr, ", ");
2544 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2545 unsaved_files[i].Length);
2546 }
2547 fprintf(stderr, "],\n");
2548 fprintf(stderr, " 'options' : %d,\n", options);
2549 fprintf(stderr, "}\n");
2550
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002551 return 0;
2552 }
2553
2554 return PTUI.result;
Steve Naroff7781daa2009-10-15 20:04:39 +00002555}
2556
Douglas Gregor6bb92ec2010-08-13 15:35:05 +00002557unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2558 return CXSaveTranslationUnit_None;
2559}
2560
2561int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2562 unsigned options) {
Douglas Gregore9386682010-08-13 05:36:37 +00002563 if (!TU)
2564 return 1;
2565
Ted Kremenek91554282010-11-16 08:15:36 +00002566 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregore9386682010-08-13 05:36:37 +00002567}
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002568
Daniel Dunbar079203f2009-12-01 03:14:51 +00002569void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002570 if (CTUnit) {
2571 // If the translation unit has been marked as unsafe to free, just discard
2572 // it.
Ted Kremenek91554282010-11-16 08:15:36 +00002573 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002574 return;
2575
Ted Kremenek91554282010-11-16 08:15:36 +00002576 delete static_cast<ASTUnit *>(CTUnit->TUData);
2577 disposeCXStringPool(CTUnit->StringPool);
2578 delete CTUnit;
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002579 }
Steve Naroff3aa2d732009-09-17 18:33:27 +00002580}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002581
Douglas Gregorde051182010-08-11 15:58:42 +00002582unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2583 return CXReparse_None;
2584}
2585
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002586struct ReparseTranslationUnitInfo {
2587 CXTranslationUnit TU;
2588 unsigned num_unsaved_files;
2589 struct CXUnsavedFile *unsaved_files;
2590 unsigned options;
2591 int result;
2592};
Douglas Gregorca5b0532010-09-23 18:47:53 +00002593
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002594static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002595 ReparseTranslationUnitInfo *RTUI =
2596 static_cast<ReparseTranslationUnitInfo*>(UserData);
2597 CXTranslationUnit TU = RTUI->TU;
2598 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2599 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2600 unsigned options = RTUI->options;
2601 (void) options;
2602 RTUI->result = 1;
2603
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002604 if (!TU)
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002605 return;
Douglas Gregorca5b0532010-09-23 18:47:53 +00002606
Ted Kremenek91554282010-11-16 08:15:36 +00002607 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorca5b0532010-09-23 18:47:53 +00002608 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002609
Ted Kremenek022a4902011-03-22 01:15:24 +00002610 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2611 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2612
2613 // Recover resources if we crash before exiting this function.
2614 llvm::CrashRecoveryContextCleanupRegistrar<
2615 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2616
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002617 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2618 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2619 const llvm::MemoryBuffer *Buffer
Douglas Gregor8e984da2010-08-04 16:47:14 +00002620 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek022a4902011-03-22 01:15:24 +00002621 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2622 Buffer));
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002623 }
2624
Ted Kremenek600b54c2011-03-22 20:16:19 +00002625 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2626 RemappedFiles->size()))
Douglas Gregorca5b0532010-09-23 18:47:53 +00002627 RTUI->result = 0;
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002628}
Douglas Gregorca5b0532010-09-23 18:47:53 +00002629
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002630int clang_reparseTranslationUnit(CXTranslationUnit TU,
2631 unsigned num_unsaved_files,
2632 struct CXUnsavedFile *unsaved_files,
2633 unsigned options) {
2634 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2635 options, 0 };
2636 llvm::CrashRecoveryContext CRC;
2637
Daniel Dunbarb7383e62010-11-05 07:19:31 +00002638 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002639 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremenek91554282010-11-16 08:15:36 +00002640 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002641 return 1;
2642 }
2643
Ted Kremenek55ccf4e2010-10-29 01:06:50 +00002644
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002645 return RTUI.result;
2646}
2647
Douglas Gregor028d3e42010-08-09 20:45:32 +00002648
Daniel Dunbar079203f2009-12-01 03:14:51 +00002649CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002650 if (!CTUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002651 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00002652
Ted Kremenek91554282010-11-16 08:15:36 +00002653 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002654 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroff38c1a7b2009-09-03 15:49:00 +00002655}
Daniel Dunbare58bd8b2009-08-28 16:30:07 +00002656
Douglas Gregord2fc7272010-01-20 00:23:15 +00002657CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00002658 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregord2fc7272010-01-20 00:23:15 +00002659 return Result;
2660}
2661
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002662} // end: extern "C"
Steve Naroffd5e8e862009-08-27 19:51:58 +00002663
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002664//===----------------------------------------------------------------------===//
Douglas Gregor4f46e782010-01-19 21:36:55 +00002665// CXSourceLocation and CXSourceRange Operations.
2666//===----------------------------------------------------------------------===//
2667
Douglas Gregor816fd362010-01-22 21:44:22 +00002668extern "C" {
2669CXSourceLocation clang_getNullLocation() {
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002670 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregor816fd362010-01-22 21:44:22 +00002671 return Result;
2672}
2673
2674unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar83a23542010-01-30 23:58:27 +00002675 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2676 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2677 loc1.int_data == loc2.int_data);
Douglas Gregor816fd362010-01-22 21:44:22 +00002678}
2679
2680CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2681 CXFile file,
2682 unsigned line,
2683 unsigned column) {
Douglas Gregor0925fbc2010-04-30 19:45:53 +00002684 if (!tu || !file)
Douglas Gregor816fd362010-01-22 21:44:22 +00002685 return clang_getNullLocation();
Douglas Gregor0925fbc2010-04-30 19:45:53 +00002686
Douglas Gregore6642762011-02-03 17:17:35 +00002687 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremenek91554282010-11-16 08:15:36 +00002688 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregore6642762011-02-03 17:17:35 +00002689 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregor816fd362010-01-22 21:44:22 +00002690 SourceLocation SLoc
Douglas Gregore6642762011-02-03 17:17:35 +00002691 = CXXUnit->getSourceManager().getLocation(File, line, column);
2692 if (SLoc.isInvalid()) {
2693 if (Logging)
2694 llvm::errs() << "clang_getLocation(\"" << File->getName()
2695 << "\", " << line << ", " << column << ") = invalid\n";
2696 return clang_getNullLocation();
2697 }
2698
2699 if (Logging)
2700 llvm::errs() << "clang_getLocation(\"" << File->getName()
2701 << "\", " << line << ", " << column << ") = "
2702 << SLoc.getRawEncoding() << "\n";
David Chisnall2e16ac52010-10-15 17:07:39 +00002703
2704 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2705}
2706
2707CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2708 CXFile file,
2709 unsigned offset) {
2710 if (!tu || !file)
2711 return clang_getNullLocation();
2712
Ted Kremenek91554282010-11-16 08:15:36 +00002713 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall2e16ac52010-10-15 17:07:39 +00002714 SourceLocation Start
2715 = CXXUnit->getSourceManager().getLocation(
2716 static_cast<const FileEntry *>(file),
2717 1, 1);
2718 if (Start.isInvalid()) return clang_getNullLocation();
2719
2720 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2721
2722 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002723
Ted Kremenek54140272010-06-28 23:54:17 +00002724 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregor816fd362010-01-22 21:44:22 +00002725}
2726
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002727CXSourceRange clang_getNullRange() {
2728 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2729 return Result;
2730}
Daniel Dunbar02968e52010-02-14 10:02:57 +00002731
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002732CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2733 if (begin.ptr_data[0] != end.ptr_data[0] ||
2734 begin.ptr_data[1] != end.ptr_data[1])
2735 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002736
2737 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002738 begin.int_data, end.int_data };
Douglas Gregor816fd362010-01-22 21:44:22 +00002739 return Result;
2740}
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002741} // end: extern "C"
Douglas Gregor816fd362010-01-22 21:44:22 +00002742
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002743static void createNullLocation(CXFile *file, unsigned *line,
2744 unsigned *column, unsigned *offset) {
2745 if (file)
2746 *file = 0;
2747 if (line)
2748 *line = 0;
2749 if (column)
2750 *column = 0;
2751 if (offset)
2752 *offset = 0;
2753 return;
2754}
2755
2756extern "C" {
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002757void clang_getInstantiationLocation(CXSourceLocation location,
2758 CXFile *file,
2759 unsigned *line,
2760 unsigned *column,
2761 unsigned *offset) {
Douglas Gregor4f46e782010-01-19 21:36:55 +00002762 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2763
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002764 if (!location.ptr_data[0] || Loc.isInvalid()) {
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002765 createNullLocation(file, line, column, offset);
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002766 return;
2767 }
2768
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002769 const SourceManager &SM =
2770 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002771 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002772
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002773 // Check that the FileID is invalid on the instantiation location.
2774 // This can manifest in invalid code.
2775 FileID fileID = SM.getFileID(InstLoc);
Douglas Gregor49f754f2011-04-20 00:21:03 +00002776 bool Invalid = false;
2777 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
2778 if (!sloc.isFile() || Invalid) {
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002779 createNullLocation(file, line, column, offset);
2780 return;
2781 }
2782
Douglas Gregor4f46e782010-01-19 21:36:55 +00002783 if (file)
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002784 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002785 if (line)
2786 *line = SM.getInstantiationLineNumber(InstLoc);
2787 if (column)
2788 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregor47751d62010-01-26 03:07:15 +00002789 if (offset)
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002790 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregor47751d62010-01-26 03:07:15 +00002791}
2792
Douglas Gregor229bebd2010-11-09 06:24:54 +00002793void clang_getSpellingLocation(CXSourceLocation location,
2794 CXFile *file,
2795 unsigned *line,
2796 unsigned *column,
2797 unsigned *offset) {
2798 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2799
2800 if (!location.ptr_data[0] || Loc.isInvalid()) {
2801 if (file)
2802 *file = 0;
2803 if (line)
2804 *line = 0;
2805 if (column)
2806 *column = 0;
2807 if (offset)
2808 *offset = 0;
2809 return;
2810 }
2811
2812 const SourceManager &SM =
2813 *static_cast<const SourceManager*>(location.ptr_data[0]);
2814 SourceLocation SpellLoc = Loc;
2815 if (SpellLoc.isMacroID()) {
2816 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2817 if (SimpleSpellingLoc.isFileID() &&
2818 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2819 SpellLoc = SimpleSpellingLoc;
2820 else
2821 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2822 }
2823
2824 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2825 FileID FID = LocInfo.first;
2826 unsigned FileOffset = LocInfo.second;
2827
2828 if (file)
2829 *file = (void *)SM.getFileEntryForID(FID);
2830 if (line)
2831 *line = SM.getLineNumber(FID, FileOffset);
2832 if (column)
2833 *column = SM.getColumnNumber(FID, FileOffset);
2834 if (offset)
2835 *offset = FileOffset;
2836}
2837
Douglas Gregor4f46e782010-01-19 21:36:55 +00002838CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002839 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002840 range.begin_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002841 return Result;
2842}
2843
2844CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002845 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002846 range.end_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002847 return Result;
2848}
2849
Douglas Gregor816fd362010-01-22 21:44:22 +00002850} // end: extern "C"
2851
Douglas Gregor4f46e782010-01-19 21:36:55 +00002852//===----------------------------------------------------------------------===//
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002853// CXFile Operations.
2854//===----------------------------------------------------------------------===//
2855
2856extern "C" {
Ted Kremenekc560b682010-02-17 00:41:20 +00002857CXString clang_getFileName(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002858 if (!SFile)
Ted Kremenek91554282010-11-16 08:15:36 +00002859 return createCXString((const char*)NULL);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002860
Steve Naroff6231f182009-10-27 14:35:18 +00002861 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenekc560b682010-02-17 00:41:20 +00002862 return createCXString(FEnt->getName());
Steve Naroff6231f182009-10-27 14:35:18 +00002863}
2864
2865time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002866 if (!SFile)
2867 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002868
Steve Naroff6231f182009-10-27 14:35:18 +00002869 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2870 return FEnt->getModificationTime();
Steve Naroff26760892009-09-25 21:45:39 +00002871}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002872
Douglas Gregor816fd362010-01-22 21:44:22 +00002873CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2874 if (!tu)
2875 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002876
Ted Kremenek91554282010-11-16 08:15:36 +00002877 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002878
Douglas Gregor816fd362010-01-22 21:44:22 +00002879 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner5159f612010-11-23 08:35:12 +00002880 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregor816fd362010-01-22 21:44:22 +00002881}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002882
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002883} // end: extern "C"
Steve Naroff26760892009-09-25 21:45:39 +00002884
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002885//===----------------------------------------------------------------------===//
2886// CXCursor Operations.
2887//===----------------------------------------------------------------------===//
2888
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002889static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregore6712982010-10-01 21:11:22 +00002890 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2891 return getDeclFromExpr(CE->getSubExpr());
2892
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002893 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2894 return RefExpr->getDecl();
Douglas Gregor263803a2010-10-22 22:24:08 +00002895 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2896 return RefExpr->getDecl();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002897 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2898 return ME->getMemberDecl();
2899 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2900 return RE->getDecl();
Douglas Gregore6712982010-10-01 21:11:22 +00002901 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCallb7bd14f2010-12-02 01:19:52 +00002902 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregore6712982010-10-01 21:11:22 +00002903
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002904 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2905 return getDeclFromExpr(CE->getCallee());
Douglas Gregor16443fd2010-11-05 21:11:19 +00002906 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2907 if (!CE->isElidable())
2908 return CE->getConstructor();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002909 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2910 return OME->getMethodDecl();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002911
Douglas Gregore6712982010-10-01 21:11:22 +00002912 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2913 return PE->getProtocol();
Douglas Gregorcdbc5392011-01-15 01:15:58 +00002914 if (SubstNonTypeTemplateParmPackExpr *NTTP
2915 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2916 return NTTP->getParameterPack();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002917 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2918 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2919 isa<ParmVarDecl>(SizeOfPack->getPack()))
2920 return SizeOfPack->getPack();
Douglas Gregore6712982010-10-01 21:11:22 +00002921
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002922 return 0;
2923}
2924
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002925static SourceLocation getLocationFromExpr(Expr *E) {
2926 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2927 return /*FIXME:*/Msg->getLeftLoc();
2928 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2929 return DRE->getLocation();
Douglas Gregor263803a2010-10-22 22:24:08 +00002930 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2931 return RefExpr->getLocation();
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002932 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2933 return Member->getMemberLoc();
2934 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2935 return Ivar->getLocation();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002936 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2937 return SizeOfPack->getPackLoc();
2938
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002939 return E->getLocStart();
2940}
2941
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002942extern "C" {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002943
2944unsigned clang_visitChildren(CXCursor parent,
Douglas Gregor71f3d942010-01-20 20:59:29 +00002945 CXCursorVisitor visitor,
2946 CXClientData client_data) {
Ted Kremenek91554282010-11-16 08:15:36 +00002947 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregorc2b97992011-03-16 23:23:30 +00002948 getCursorASTUnit(parent)->getMaxPCHLevel(),
2949 false);
Douglas Gregor71f3d942010-01-20 20:59:29 +00002950 return CursorVis.VisitChildren(parent);
2951}
2952
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002953#ifndef __has_feature
2954#define __has_feature(x) 0
2955#endif
2956#if __has_feature(blocks)
2957typedef enum CXChildVisitResult
2958 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2959
2960static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2961 CXClientData client_data) {
2962 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2963 return block(cursor, parent);
2964}
2965#else
2966// If we are compiled with a compiler that doesn't have native blocks support,
2967// define and call the block manually, so the
2968typedef struct _CXChildVisitResult
2969{
2970 void *isa;
2971 int flags;
2972 int reserved;
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002973 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2974 CXCursor);
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002975} *CXCursorVisitorBlock;
2976
2977static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2978 CXClientData client_data) {
2979 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2980 return block->invoke(block, cursor, parent);
2981}
2982#endif
2983
2984
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002985unsigned clang_visitChildrenWithBlock(CXCursor parent,
2986 CXCursorVisitorBlock block) {
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002987 return clang_visitChildren(parent, visitWithBlock, block);
2988}
2989
Douglas Gregordd969c82010-01-20 21:45:58 +00002990static CXString getDeclSpelling(Decl *D) {
2991 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002992 if (!ND) {
2993 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2994 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2995 return createCXString(Property->getIdentifier()->getName());
2996
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002997 return createCXString("");
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002998 }
2999
Douglas Gregordd969c82010-01-20 21:45:58 +00003000 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003001 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf441baf2010-02-17 00:41:40 +00003002
Douglas Gregordd969c82010-01-20 21:45:58 +00003003 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
3004 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3005 // and returns different names. NamedDecl returns the class name and
3006 // ObjCCategoryImplDecl returns the category name.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003007 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf441baf2010-02-17 00:41:40 +00003008
Douglas Gregor01a430132010-09-01 03:07:18 +00003009 if (isa<UsingDirectiveDecl>(D))
3010 return createCXString("");
3011
Ted Kremenek08de5c12010-05-19 21:51:10 +00003012 llvm::SmallString<1024> S;
3013 llvm::raw_svector_ostream os(S);
3014 ND->printName(os);
3015
3016 return createCXString(os.str());
Douglas Gregordd969c82010-01-20 21:45:58 +00003017}
Ted Kremenekf441baf2010-02-17 00:41:40 +00003018
Daniel Dunbar079203f2009-12-01 03:14:51 +00003019CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregord2fc7272010-01-20 00:23:15 +00003020 if (clang_isTranslationUnit(C.kind))
Ted Kremenek91554282010-11-16 08:15:36 +00003021 return clang_getTranslationUnitSpelling(
3022 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregord2fc7272010-01-20 00:23:15 +00003023
Steve Naroff80a766b2009-09-02 18:26:48 +00003024 if (clang_isReference(C.kind)) {
3025 switch (C.kind) {
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003026 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor6c8959b2010-01-16 14:00:32 +00003027 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003028 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003029 }
3030 case CXCursor_ObjCClassRef: {
Douglas Gregor46d66142010-01-16 17:14:40 +00003031 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003032 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003033 }
3034 case CXCursor_ObjCProtocolRef: {
Douglas Gregoref6eb842010-01-16 15:44:18 +00003035 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003036 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003037 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003038 }
Ted Kremenekae9e2212010-08-27 21:34:58 +00003039 case CXCursor_CXXBaseSpecifier: {
3040 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3041 return createCXString(B->getType().getAsString());
3042 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003043 case CXCursor_TypeRef: {
3044 TypeDecl *Type = getCursorTypeRef(C).first;
3045 assert(Type && "Missing type decl");
3046
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003047 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3048 getAsString());
Douglas Gregor93f89952010-01-21 16:28:34 +00003049 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00003050 case CXCursor_TemplateRef: {
3051 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregora89314e2010-08-31 23:48:11 +00003052 assert(Template && "Missing template decl");
Douglas Gregora23e8f72010-08-31 20:37:03 +00003053
3054 return createCXString(Template->getNameAsString());
3055 }
Douglas Gregora89314e2010-08-31 23:48:11 +00003056
3057 case CXCursor_NamespaceRef: {
3058 NamedDecl *NS = getCursorNamespaceRef(C).first;
3059 assert(NS && "Missing namespace decl");
3060
3061 return createCXString(NS->getNameAsString());
3062 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003063
Douglas Gregorf3af3112010-09-09 21:42:20 +00003064 case CXCursor_MemberRef: {
3065 FieldDecl *Field = getCursorMemberRef(C).first;
3066 assert(Field && "Missing member decl");
3067
3068 return createCXString(Field->getNameAsString());
3069 }
3070
Douglas Gregora93ab662010-09-10 00:22:18 +00003071 case CXCursor_LabelRef: {
3072 LabelStmt *Label = getCursorLabelRef(C).first;
3073 assert(Label && "Missing label");
3074
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003075 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00003076 }
3077
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003078 case CXCursor_OverloadedDeclRef: {
3079 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3080 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3081 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3082 return createCXString(ND->getNameAsString());
3083 return createCXString("");
3084 }
3085 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3086 return createCXString(E->getName().getAsString());
3087 OverloadedTemplateStorage *Ovl
3088 = Storage.get<OverloadedTemplateStorage*>();
3089 if (Ovl->size() == 0)
3090 return createCXString("");
3091 return createCXString((*Ovl->begin())->getNameAsString());
3092 }
3093
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003094 default:
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003095 return createCXString("<not implemented>");
Steve Naroff80a766b2009-09-02 18:26:48 +00003096 }
3097 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003098
3099 if (clang_isExpression(C.kind)) {
3100 Decl *D = getDeclFromExpr(getCursorExpr(C));
3101 if (D)
Douglas Gregordd969c82010-01-20 21:45:58 +00003102 return getDeclSpelling(D);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003103 return createCXString("");
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003104 }
3105
Douglas Gregora93ab662010-09-10 00:22:18 +00003106 if (clang_isStatement(C.kind)) {
3107 Stmt *S = getCursorStmt(C);
3108 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003109 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00003110
3111 return createCXString("");
3112 }
3113
Douglas Gregor065f8d12010-03-18 17:52:52 +00003114 if (C.kind == CXCursor_MacroInstantiation)
3115 return createCXString(getCursorMacroInstantiation(C)->getName()
3116 ->getNameStart());
3117
Douglas Gregor06d6d322010-03-18 18:04:21 +00003118 if (C.kind == CXCursor_MacroDefinition)
3119 return createCXString(getCursorMacroDefinition(C)->getName()
3120 ->getNameStart());
3121
Douglas Gregor796d76a2010-10-20 22:00:55 +00003122 if (C.kind == CXCursor_InclusionDirective)
3123 return createCXString(getCursorInclusionDirective(C)->getFileName());
3124
Douglas Gregor5bce76c2010-01-25 16:56:17 +00003125 if (clang_isDeclaration(C.kind))
3126 return getDeclSpelling(getCursorDecl(C));
Ted Kremenek29004672010-02-17 00:41:32 +00003127
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003128 return createCXString("");
Steve Naroff80a766b2009-09-02 18:26:48 +00003129}
3130
Douglas Gregor97c75712010-10-02 22:49:11 +00003131CXString clang_getCursorDisplayName(CXCursor C) {
3132 if (!clang_isDeclaration(C.kind))
3133 return clang_getCursorSpelling(C);
3134
3135 Decl *D = getCursorDecl(C);
3136 if (!D)
3137 return createCXString("");
3138
3139 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3140 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3141 D = FunTmpl->getTemplatedDecl();
3142
3143 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3144 llvm::SmallString<64> Str;
3145 llvm::raw_svector_ostream OS(Str);
3146 OS << Function->getNameAsString();
3147 if (Function->getPrimaryTemplate())
3148 OS << "<>";
3149 OS << "(";
3150 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3151 if (I)
3152 OS << ", ";
3153 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3154 }
3155
3156 if (Function->isVariadic()) {
3157 if (Function->getNumParams())
3158 OS << ", ";
3159 OS << "...";
3160 }
3161 OS << ")";
3162 return createCXString(OS.str());
3163 }
3164
3165 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3166 llvm::SmallString<64> Str;
3167 llvm::raw_svector_ostream OS(Str);
3168 OS << ClassTemplate->getNameAsString();
3169 OS << "<";
3170 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3171 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3172 if (I)
3173 OS << ", ";
3174
3175 NamedDecl *Param = Params->getParam(I);
3176 if (Param->getIdentifier()) {
3177 OS << Param->getIdentifier()->getName();
3178 continue;
3179 }
3180
3181 // There is no parameter name, which makes this tricky. Try to come up
3182 // with something useful that isn't too long.
3183 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3184 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3185 else if (NonTypeTemplateParmDecl *NTTP
3186 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3187 OS << NTTP->getType().getAsString(Policy);
3188 else
3189 OS << "template<...> class";
3190 }
3191
3192 OS << ">";
3193 return createCXString(OS.str());
3194 }
3195
3196 if (ClassTemplateSpecializationDecl *ClassSpec
3197 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3198 // If the type was explicitly written, use that.
3199 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3200 return createCXString(TSInfo->getType().getAsString(Policy));
3201
3202 llvm::SmallString<64> Str;
3203 llvm::raw_svector_ostream OS(Str);
3204 OS << ClassSpec->getNameAsString();
3205 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor1ccc8412010-11-07 23:05:16 +00003206 ClassSpec->getTemplateArgs().data(),
3207 ClassSpec->getTemplateArgs().size(),
Douglas Gregor97c75712010-10-02 22:49:11 +00003208 Policy);
3209 return createCXString(OS.str());
3210 }
3211
3212 return clang_getCursorSpelling(C);
3213}
3214
Ted Kremenek29004672010-02-17 00:41:32 +00003215CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff1054e602009-08-31 00:59:03 +00003216 switch (Kind) {
Ted Kremenek29004672010-02-17 00:41:32 +00003217 case CXCursor_FunctionDecl:
3218 return createCXString("FunctionDecl");
3219 case CXCursor_TypedefDecl:
3220 return createCXString("TypedefDecl");
3221 case CXCursor_EnumDecl:
3222 return createCXString("EnumDecl");
3223 case CXCursor_EnumConstantDecl:
3224 return createCXString("EnumConstantDecl");
3225 case CXCursor_StructDecl:
3226 return createCXString("StructDecl");
3227 case CXCursor_UnionDecl:
3228 return createCXString("UnionDecl");
3229 case CXCursor_ClassDecl:
3230 return createCXString("ClassDecl");
3231 case CXCursor_FieldDecl:
3232 return createCXString("FieldDecl");
3233 case CXCursor_VarDecl:
3234 return createCXString("VarDecl");
3235 case CXCursor_ParmDecl:
3236 return createCXString("ParmDecl");
3237 case CXCursor_ObjCInterfaceDecl:
3238 return createCXString("ObjCInterfaceDecl");
3239 case CXCursor_ObjCCategoryDecl:
3240 return createCXString("ObjCCategoryDecl");
3241 case CXCursor_ObjCProtocolDecl:
3242 return createCXString("ObjCProtocolDecl");
3243 case CXCursor_ObjCPropertyDecl:
3244 return createCXString("ObjCPropertyDecl");
3245 case CXCursor_ObjCIvarDecl:
3246 return createCXString("ObjCIvarDecl");
3247 case CXCursor_ObjCInstanceMethodDecl:
3248 return createCXString("ObjCInstanceMethodDecl");
3249 case CXCursor_ObjCClassMethodDecl:
3250 return createCXString("ObjCClassMethodDecl");
3251 case CXCursor_ObjCImplementationDecl:
3252 return createCXString("ObjCImplementationDecl");
3253 case CXCursor_ObjCCategoryImplDecl:
3254 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek225b8e32010-04-13 23:39:06 +00003255 case CXCursor_CXXMethod:
3256 return createCXString("CXXMethod");
Ted Kremenek29004672010-02-17 00:41:32 +00003257 case CXCursor_UnexposedDecl:
3258 return createCXString("UnexposedDecl");
3259 case CXCursor_ObjCSuperClassRef:
3260 return createCXString("ObjCSuperClassRef");
3261 case CXCursor_ObjCProtocolRef:
3262 return createCXString("ObjCProtocolRef");
3263 case CXCursor_ObjCClassRef:
3264 return createCXString("ObjCClassRef");
3265 case CXCursor_TypeRef:
3266 return createCXString("TypeRef");
Douglas Gregora23e8f72010-08-31 20:37:03 +00003267 case CXCursor_TemplateRef:
3268 return createCXString("TemplateRef");
Douglas Gregora89314e2010-08-31 23:48:11 +00003269 case CXCursor_NamespaceRef:
3270 return createCXString("NamespaceRef");
Douglas Gregorf3af3112010-09-09 21:42:20 +00003271 case CXCursor_MemberRef:
3272 return createCXString("MemberRef");
Douglas Gregora93ab662010-09-10 00:22:18 +00003273 case CXCursor_LabelRef:
3274 return createCXString("LabelRef");
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003275 case CXCursor_OverloadedDeclRef:
3276 return createCXString("OverloadedDeclRef");
Ted Kremenek29004672010-02-17 00:41:32 +00003277 case CXCursor_UnexposedExpr:
3278 return createCXString("UnexposedExpr");
Ted Kremenek33b9a422010-04-11 21:47:37 +00003279 case CXCursor_BlockExpr:
3280 return createCXString("BlockExpr");
Ted Kremenek29004672010-02-17 00:41:32 +00003281 case CXCursor_DeclRefExpr:
3282 return createCXString("DeclRefExpr");
3283 case CXCursor_MemberRefExpr:
3284 return createCXString("MemberRefExpr");
3285 case CXCursor_CallExpr:
3286 return createCXString("CallExpr");
3287 case CXCursor_ObjCMessageExpr:
3288 return createCXString("ObjCMessageExpr");
3289 case CXCursor_UnexposedStmt:
3290 return createCXString("UnexposedStmt");
Douglas Gregora93ab662010-09-10 00:22:18 +00003291 case CXCursor_LabelStmt:
3292 return createCXString("LabelStmt");
Ted Kremenek29004672010-02-17 00:41:32 +00003293 case CXCursor_InvalidFile:
3294 return createCXString("InvalidFile");
Ted Kremenek00da3b92010-03-19 20:39:05 +00003295 case CXCursor_InvalidCode:
3296 return createCXString("InvalidCode");
Ted Kremenek29004672010-02-17 00:41:32 +00003297 case CXCursor_NoDeclFound:
3298 return createCXString("NoDeclFound");
3299 case CXCursor_NotImplemented:
3300 return createCXString("NotImplemented");
3301 case CXCursor_TranslationUnit:
3302 return createCXString("TranslationUnit");
Ted Kremenekbff31432010-02-18 03:09:07 +00003303 case CXCursor_UnexposedAttr:
3304 return createCXString("UnexposedAttr");
3305 case CXCursor_IBActionAttr:
3306 return createCXString("attribute(ibaction)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003307 case CXCursor_IBOutletAttr:
3308 return createCXString("attribute(iboutlet)");
Ted Kremenek26bde772010-05-19 17:38:06 +00003309 case CXCursor_IBOutletCollectionAttr:
3310 return createCXString("attribute(iboutletcollection)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003311 case CXCursor_PreprocessingDirective:
3312 return createCXString("preprocessing directive");
Douglas Gregor06d6d322010-03-18 18:04:21 +00003313 case CXCursor_MacroDefinition:
3314 return createCXString("macro definition");
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003315 case CXCursor_MacroInstantiation:
3316 return createCXString("macro instantiation");
Douglas Gregor796d76a2010-10-20 22:00:55 +00003317 case CXCursor_InclusionDirective:
3318 return createCXString("inclusion directive");
Ted Kremenekbd67fb22010-05-06 23:38:21 +00003319 case CXCursor_Namespace:
3320 return createCXString("Namespace");
Ted Kremenekb80cba52010-05-07 01:04:29 +00003321 case CXCursor_LinkageSpec:
3322 return createCXString("LinkageSpec");
Ted Kremenekae9e2212010-08-27 21:34:58 +00003323 case CXCursor_CXXBaseSpecifier:
3324 return createCXString("C++ base class specifier");
Douglas Gregor12bca222010-08-31 14:41:23 +00003325 case CXCursor_Constructor:
3326 return createCXString("CXXConstructor");
3327 case CXCursor_Destructor:
3328 return createCXString("CXXDestructor");
3329 case CXCursor_ConversionFunction:
3330 return createCXString("CXXConversion");
Douglas Gregor713602b2010-08-31 17:01:39 +00003331 case CXCursor_TemplateTypeParameter:
3332 return createCXString("TemplateTypeParameter");
3333 case CXCursor_NonTypeTemplateParameter:
3334 return createCXString("NonTypeTemplateParameter");
3335 case CXCursor_TemplateTemplateParameter:
3336 return createCXString("TemplateTemplateParameter");
3337 case CXCursor_FunctionTemplate:
3338 return createCXString("FunctionTemplate");
Douglas Gregor1fbaeb12010-08-31 19:02:00 +00003339 case CXCursor_ClassTemplate:
3340 return createCXString("ClassTemplate");
Douglas Gregorf96abb22010-08-31 19:31:58 +00003341 case CXCursor_ClassTemplatePartialSpecialization:
3342 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregora89314e2010-08-31 23:48:11 +00003343 case CXCursor_NamespaceAlias:
3344 return createCXString("NamespaceAlias");
Douglas Gregor01a430132010-09-01 03:07:18 +00003345 case CXCursor_UsingDirective:
3346 return createCXString("UsingDirective");
Douglas Gregora9aa29c2010-09-01 19:52:22 +00003347 case CXCursor_UsingDeclaration:
3348 return createCXString("UsingDeclaration");
Richard Smithdda56e42011-04-15 14:24:37 +00003349 case CXCursor_TypeAliasDecl:
3350 return createCXString("TypeAliasDecl");
Steve Naroff1054e602009-08-31 00:59:03 +00003351 }
Ted Kremenek29004672010-02-17 00:41:32 +00003352
Ted Kremenek4ba52632010-01-16 02:02:09 +00003353 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremenek91554282010-11-16 08:15:36 +00003354 return createCXString((const char*) 0);
Steve Naroffd5e8e862009-08-27 19:51:58 +00003355}
Steve Naroff1054e602009-08-31 00:59:03 +00003356
Ted Kremenek29004672010-02-17 00:41:32 +00003357enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3358 CXCursor parent,
Douglas Gregor562c1f92010-01-22 19:49:59 +00003359 CXClientData client_data) {
3360 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor16443fd2010-11-05 21:11:19 +00003361
3362 // If our current best cursor is the construction of a temporary object,
3363 // don't replace that cursor with a type reference, because we want
3364 // clang_getCursor() to point at the constructor.
3365 if (clang_isExpression(BestCursor->kind) &&
3366 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3367 cursor.kind == CXCursor_TypeRef)
3368 return CXChildVisit_Recurse;
3369
Douglas Gregor3046b4d2010-12-10 07:23:11 +00003370 // Don't override a preprocessing cursor with another preprocessing
3371 // cursor; we want the outermost preprocessing cursor.
3372 if (clang_isPreprocessing(cursor.kind) &&
3373 clang_isPreprocessing(BestCursor->kind))
3374 return CXChildVisit_Recurse;
3375
Douglas Gregor562c1f92010-01-22 19:49:59 +00003376 *BestCursor = cursor;
3377 return CXChildVisit_Recurse;
3378}
Ted Kremenek29004672010-02-17 00:41:32 +00003379
Douglas Gregor816fd362010-01-22 21:44:22 +00003380CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3381 if (!TU)
Ted Kremeneke34cbde2010-01-14 01:51:23 +00003382 return clang_getNullCursor();
Ted Kremenek29004672010-02-17 00:41:32 +00003383
Ted Kremenek91554282010-11-16 08:15:36 +00003384 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00003385 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3386
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003387 // Translate the given source location to make it point at the beginning of
3388 // the token under the cursor.
Ted Kremenek97a45372010-01-25 22:34:44 +00003389 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremenek1e589f22010-07-29 00:52:07 +00003390
3391 // Guard against an invalid SourceLocation, or we may assert in one
3392 // of the following calls.
3393 if (SLoc.isInvalid())
3394 return clang_getNullCursor();
3395
Douglas Gregor15417cf2010-11-03 00:35:38 +00003396 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003397 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3398 CXXUnit->getASTContext().getLangOptions());
3399
Douglas Gregor562c1f92010-01-22 19:49:59 +00003400 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3401 if (SLoc.isValid()) {
Douglas Gregor562c1f92010-01-22 19:49:59 +00003402 // FIXME: Would be great to have a "hint" cursor, then walk from that
3403 // hint cursor upward until we find a cursor whose source range encloses
3404 // the region of interest, rather than starting from the translation unit.
Ted Kremenek91554282010-11-16 08:15:36 +00003405 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3406 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregorc2b97992011-03-16 23:23:30 +00003407 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor562c1f92010-01-22 19:49:59 +00003408 CursorVis.VisitChildren(Parent);
Steve Naroff54f22fb2009-09-15 20:25:34 +00003409 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003410
3411 if (Logging) {
3412 CXFile SearchFile;
3413 unsigned SearchLine, SearchColumn;
3414 CXFile ResultFile;
3415 unsigned ResultLine, ResultColumn;
Douglas Gregor29ee4222010-11-17 17:14:07 +00003416 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3417 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor15417cf2010-11-03 00:35:38 +00003418 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3419
3420 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3421 0);
3422 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3423 &ResultColumn, 0);
3424 SearchFileName = clang_getFileName(SearchFile);
3425 ResultFileName = clang_getFileName(ResultFile);
3426 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003427 USR = clang_getCursorUSR(Result);
3428 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor15417cf2010-11-03 00:35:38 +00003429 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3430 clang_getCString(KindSpelling),
Douglas Gregor29ee4222010-11-17 17:14:07 +00003431 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3432 clang_getCString(USR), IsDef);
Douglas Gregor15417cf2010-11-03 00:35:38 +00003433 clang_disposeString(SearchFileName);
3434 clang_disposeString(ResultFileName);
3435 clang_disposeString(KindSpelling);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003436 clang_disposeString(USR);
Douglas Gregor4a5bd5f2010-12-10 01:45:00 +00003437
3438 CXCursor Definition = clang_getCursorDefinition(Result);
3439 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3440 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3441 CXString DefinitionKindSpelling
3442 = clang_getCursorKindSpelling(Definition.kind);
3443 CXFile DefinitionFile;
3444 unsigned DefinitionLine, DefinitionColumn;
3445 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3446 &DefinitionLine, &DefinitionColumn, 0);
3447 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3448 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3449 clang_getCString(DefinitionKindSpelling),
3450 clang_getCString(DefinitionFileName),
3451 DefinitionLine, DefinitionColumn);
3452 clang_disposeString(DefinitionFileName);
3453 clang_disposeString(DefinitionKindSpelling);
3454 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003455 }
3456
Ted Kremenek29004672010-02-17 00:41:32 +00003457 return Result;
Steve Naroffd5e8e862009-08-27 19:51:58 +00003458}
3459
Ted Kremeneke05d7802009-11-17 19:28:59 +00003460CXCursor clang_getNullCursor(void) {
Douglas Gregor58552bc2010-01-20 23:34:41 +00003461 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremeneke05d7802009-11-17 19:28:59 +00003462}
3463
3464unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00003465 return X == Y;
Ted Kremeneke05d7802009-11-17 19:28:59 +00003466}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00003467
Douglas Gregor06a3f302010-11-20 00:09:34 +00003468unsigned clang_hashCursor(CXCursor C) {
3469 unsigned Index = 0;
3470 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3471 Index = 1;
3472
3473 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3474 std::make_pair(C.kind, C.data[Index]));
3475}
3476
Daniel Dunbar079203f2009-12-01 03:14:51 +00003477unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff54f22fb2009-09-15 20:25:34 +00003478 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3479}
3480
Daniel Dunbar079203f2009-12-01 03:14:51 +00003481unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff1054e602009-08-31 00:59:03 +00003482 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3483}
Steve Naroff772c1a42009-08-31 14:26:51 +00003484
Daniel Dunbar079203f2009-12-01 03:14:51 +00003485unsigned clang_isReference(enum CXCursorKind K) {
Steve Naroff80a766b2009-09-02 18:26:48 +00003486 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3487}
3488
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003489unsigned clang_isExpression(enum CXCursorKind K) {
3490 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3491}
3492
3493unsigned clang_isStatement(enum CXCursorKind K) {
3494 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3495}
3496
Douglas Gregord2fc7272010-01-20 00:23:15 +00003497unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3498 return K == CXCursor_TranslationUnit;
3499}
3500
Douglas Gregor92a524f2010-03-18 00:42:48 +00003501unsigned clang_isPreprocessing(enum CXCursorKind K) {
3502 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3503}
3504
Ted Kremenekff9021b2010-03-08 21:17:29 +00003505unsigned clang_isUnexposed(enum CXCursorKind K) {
3506 switch (K) {
3507 case CXCursor_UnexposedDecl:
3508 case CXCursor_UnexposedExpr:
3509 case CXCursor_UnexposedStmt:
3510 case CXCursor_UnexposedAttr:
3511 return true;
3512 default:
3513 return false;
3514 }
3515}
3516
Daniel Dunbar079203f2009-12-01 03:14:51 +00003517CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroffef9618b2009-09-04 15:44:05 +00003518 return C.kind;
3519}
3520
Douglas Gregor66a58812010-01-18 22:46:11 +00003521CXSourceLocation clang_getCursorLocation(CXCursor C) {
3522 if (clang_isReference(C.kind)) {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003523 switch (C.kind) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00003524 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003525 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3526 = getCursorObjCSuperClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003527 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003528 }
3529
Ted Kremenekf441baf2010-02-17 00:41:40 +00003530 case CXCursor_ObjCProtocolRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003531 std::pair<ObjCProtocolDecl *, SourceLocation> P
3532 = getCursorObjCProtocolRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003533 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003534 }
3535
Ted Kremenekf441baf2010-02-17 00:41:40 +00003536 case CXCursor_ObjCClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003537 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3538 = getCursorObjCClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003539 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003540 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003541
Ted Kremenekf441baf2010-02-17 00:41:40 +00003542 case CXCursor_TypeRef: {
Douglas Gregor93f89952010-01-21 16:28:34 +00003543 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003544 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor93f89952010-01-21 16:28:34 +00003545 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00003546
3547 case CXCursor_TemplateRef: {
3548 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3549 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3550 }
3551
Douglas Gregora89314e2010-08-31 23:48:11 +00003552 case CXCursor_NamespaceRef: {
3553 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3554 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3555 }
3556
Douglas Gregorf3af3112010-09-09 21:42:20 +00003557 case CXCursor_MemberRef: {
3558 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3559 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3560 }
3561
Ted Kremenekae9e2212010-08-27 21:34:58 +00003562 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor3478c752010-10-02 19:51:13 +00003563 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3564 if (!BaseSpec)
3565 return clang_getNullLocation();
3566
3567 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3568 return cxloc::translateSourceLocation(getCursorContext(C),
3569 TSInfo->getTypeLoc().getBeginLoc());
3570
3571 return cxloc::translateSourceLocation(getCursorContext(C),
3572 BaseSpec->getSourceRange().getBegin());
Ted Kremenekae9e2212010-08-27 21:34:58 +00003573 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003574
Douglas Gregora93ab662010-09-10 00:22:18 +00003575 case CXCursor_LabelRef: {
3576 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3577 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3578 }
3579
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003580 case CXCursor_OverloadedDeclRef:
3581 return cxloc::translateSourceLocation(getCursorContext(C),
3582 getCursorOverloadedDeclRef(C).second);
3583
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003584 default:
3585 // FIXME: Need a way to enumerate all non-reference cases.
3586 llvm_unreachable("Missed a reference kind");
3587 }
Douglas Gregor66a58812010-01-18 22:46:11 +00003588 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003589
3590 if (clang_isExpression(C.kind))
Ted Kremenekf441baf2010-02-17 00:41:40 +00003591 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003592 getLocationFromExpr(getCursorExpr(C)));
3593
Douglas Gregora93ab662010-09-10 00:22:18 +00003594 if (clang_isStatement(C.kind))
3595 return cxloc::translateSourceLocation(getCursorContext(C),
3596 getCursorStmt(C)->getLocStart());
3597
Douglas Gregor92a524f2010-03-18 00:42:48 +00003598 if (C.kind == CXCursor_PreprocessingDirective) {
3599 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3600 return cxloc::translateSourceLocation(getCursorContext(C), L);
3601 }
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003602
3603 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor065f8d12010-03-18 17:52:52 +00003604 SourceLocation L
3605 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003606 return cxloc::translateSourceLocation(getCursorContext(C), L);
3607 }
Douglas Gregor06d6d322010-03-18 18:04:21 +00003608
3609 if (C.kind == CXCursor_MacroDefinition) {
3610 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3611 return cxloc::translateSourceLocation(getCursorContext(C), L);
3612 }
Douglas Gregor796d76a2010-10-20 22:00:55 +00003613
3614 if (C.kind == CXCursor_InclusionDirective) {
3615 SourceLocation L
3616 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3617 return cxloc::translateSourceLocation(getCursorContext(C), L);
3618 }
3619
Ted Kremenek8278a322010-05-12 06:16:13 +00003620 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003621 return clang_getNullLocation();
Douglas Gregor66a58812010-01-18 22:46:11 +00003622
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003623 Decl *D = getCursorDecl(C);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003624 SourceLocation Loc = D->getLocation();
3625 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3626 Loc = Class->getClassLoc();
Ted Kremenek818e5c12010-11-01 23:26:51 +00003627 // FIXME: Multiple variables declared in a single declaration
3628 // currently lack the information needed to correctly determine their
3629 // ranges when accounting for the type-specifier. We use context
3630 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3631 // and if so, whether it is the first decl.
3632 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3633 if (!cxcursor::isFirstInDeclGroup(C))
3634 Loc = VD->getLocation();
3635 }
3636
Douglas Gregor7bf6b8a2010-03-22 15:53:50 +00003637 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor66a58812010-01-18 22:46:11 +00003638}
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003639
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003640} // end extern "C"
3641
3642static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003643 if (clang_isReference(C.kind)) {
3644 switch (C.kind) {
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003645 case CXCursor_ObjCSuperClassRef:
3646 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003647
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003648 case CXCursor_ObjCProtocolRef:
3649 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003650
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003651 case CXCursor_ObjCClassRef:
3652 return getCursorObjCClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003653
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003654 case CXCursor_TypeRef:
3655 return getCursorTypeRef(C).second;
Douglas Gregora23e8f72010-08-31 20:37:03 +00003656
3657 case CXCursor_TemplateRef:
3658 return getCursorTemplateRef(C).second;
3659
Douglas Gregora89314e2010-08-31 23:48:11 +00003660 case CXCursor_NamespaceRef:
3661 return getCursorNamespaceRef(C).second;
Douglas Gregorf3af3112010-09-09 21:42:20 +00003662
3663 case CXCursor_MemberRef:
3664 return getCursorMemberRef(C).second;
3665
Ted Kremenekae9e2212010-08-27 21:34:58 +00003666 case CXCursor_CXXBaseSpecifier:
Douglas Gregor3478c752010-10-02 19:51:13 +00003667 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor93f89952010-01-21 16:28:34 +00003668
Douglas Gregora93ab662010-09-10 00:22:18 +00003669 case CXCursor_LabelRef:
3670 return getCursorLabelRef(C).second;
3671
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003672 case CXCursor_OverloadedDeclRef:
3673 return getCursorOverloadedDeclRef(C).second;
3674
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003675 default:
3676 // FIXME: Need a way to enumerate all non-reference cases.
3677 llvm_unreachable("Missed a reference kind");
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003678 }
3679 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003680
3681 if (clang_isExpression(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003682 return getCursorExpr(C)->getSourceRange();
Douglas Gregor562c1f92010-01-22 19:49:59 +00003683
3684 if (clang_isStatement(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003685 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003686
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003687 if (C.kind == CXCursor_PreprocessingDirective)
3688 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003689
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003690 if (C.kind == CXCursor_MacroInstantiation)
3691 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor06d6d322010-03-18 18:04:21 +00003692
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003693 if (C.kind == CXCursor_MacroDefinition)
3694 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregor796d76a2010-10-20 22:00:55 +00003695
3696 if (C.kind == CXCursor_InclusionDirective)
3697 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3698
Ted Kremenek818e5c12010-11-01 23:26:51 +00003699 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3700 Decl *D = cxcursor::getCursorDecl(C);
3701 SourceRange R = D->getSourceRange();
3702 // FIXME: Multiple variables declared in a single declaration
3703 // currently lack the information needed to correctly determine their
3704 // ranges when accounting for the type-specifier. We use context
3705 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3706 // and if so, whether it is the first decl.
3707 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3708 if (!cxcursor::isFirstInDeclGroup(C))
3709 R.setBegin(VD->getLocation());
3710 }
3711 return R;
3712 }
Douglas Gregor29ee4222010-11-17 17:14:07 +00003713 return SourceRange();
3714}
3715
3716/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3717/// the decl-specifier-seq for declarations.
3718static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3719 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3720 Decl *D = cxcursor::getCursorDecl(C);
3721 SourceRange R = D->getSourceRange();
Douglas Gregor29ee4222010-11-17 17:14:07 +00003722
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00003723 // Adjust the start of the location for declarations preceded by
3724 // declaration specifiers.
3725 SourceLocation StartLoc;
3726 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3727 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3728 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3729 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3730 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3731 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3732 }
3733
3734 if (StartLoc.isValid() && R.getBegin().isValid() &&
3735 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3736 R.setBegin(StartLoc);
3737
3738 // FIXME: Multiple variables declared in a single declaration
3739 // currently lack the information needed to correctly determine their
3740 // ranges when accounting for the type-specifier. We use context
3741 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3742 // and if so, whether it is the first decl.
3743 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3744 if (!cxcursor::isFirstInDeclGroup(C))
3745 R.setBegin(VD->getLocation());
Douglas Gregor29ee4222010-11-17 17:14:07 +00003746 }
3747
3748 return R;
3749 }
3750
3751 return getRawCursorExtent(C);
3752}
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003753
3754extern "C" {
3755
3756CXSourceRange clang_getCursorExtent(CXCursor C) {
3757 SourceRange R = getRawCursorExtent(C);
3758 if (R.isInvalid())
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003759 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003760
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003761 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003762}
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003763
3764CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003765 if (clang_isInvalid(C.kind))
3766 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003767
Ted Kremenek91554282010-11-16 08:15:36 +00003768 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003769 if (clang_isDeclaration(C.kind)) {
3770 Decl *D = getCursorDecl(C);
3771 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003772 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003773 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003774 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003775 if (ObjCForwardProtocolDecl *Protocols
3776 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003777 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00003778 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3779 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3780 return MakeCXCursor(Property, tu);
3781
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003782 return C;
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003783 }
3784
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003785 if (clang_isExpression(C.kind)) {
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003786 Expr *E = getCursorExpr(C);
3787 Decl *D = getDeclFromExpr(E);
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003788 if (D)
Ted Kremenek91554282010-11-16 08:15:36 +00003789 return MakeCXCursor(D, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003790
3791 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremenek91554282010-11-16 08:15:36 +00003792 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003793
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003794 return clang_getNullCursor();
3795 }
3796
Douglas Gregora93ab662010-09-10 00:22:18 +00003797 if (clang_isStatement(C.kind)) {
3798 Stmt *S = getCursorStmt(C);
3799 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek6f7008d2011-03-15 23:47:49 +00003800 if (LabelDecl *label = Goto->getLabel())
3801 if (LabelStmt *labelS = label->getStmt())
3802 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003803
3804 return clang_getNullCursor();
3805 }
3806
Douglas Gregor78ae2482010-03-18 18:23:03 +00003807 if (C.kind == CXCursor_MacroInstantiation) {
3808 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003809 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregor78ae2482010-03-18 18:23:03 +00003810 }
3811
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003812 if (!clang_isReference(C.kind))
3813 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003814
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003815 switch (C.kind) {
3816 case CXCursor_ObjCSuperClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003817 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003818
3819 case CXCursor_ObjCProtocolRef: {
Ted Kremenek91554282010-11-16 08:15:36 +00003820 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003821
3822 case CXCursor_ObjCClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003823 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor93f89952010-01-21 16:28:34 +00003824
Ted Kremenekf441baf2010-02-17 00:41:40 +00003825 case CXCursor_TypeRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003826 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003827
3828 case CXCursor_TemplateRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003829 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003830
Douglas Gregora89314e2010-08-31 23:48:11 +00003831 case CXCursor_NamespaceRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003832 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregora89314e2010-08-31 23:48:11 +00003833
Douglas Gregorf3af3112010-09-09 21:42:20 +00003834 case CXCursor_MemberRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003835 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregorf3af3112010-09-09 21:42:20 +00003836
Ted Kremenekae9e2212010-08-27 21:34:58 +00003837 case CXCursor_CXXBaseSpecifier: {
3838 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3839 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremenek91554282010-11-16 08:15:36 +00003840 tu ));
Ted Kremenekae9e2212010-08-27 21:34:58 +00003841 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003842
Douglas Gregora93ab662010-09-10 00:22:18 +00003843 case CXCursor_LabelRef:
3844 // FIXME: We end up faking the "parent" declaration here because we
3845 // don't want to make CXCursor larger.
3846 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremenek91554282010-11-16 08:15:36 +00003847 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3848 .getTranslationUnitDecl(),
3849 tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003850
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003851 case CXCursor_OverloadedDeclRef:
3852 return C;
3853
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003854 default:
3855 // We would prefer to enumerate all non-reference cursor kinds here.
3856 llvm_unreachable("Unhandled reference cursor kind");
3857 break;
3858 }
3859 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003860
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003861 return clang_getNullCursor();
3862}
3863
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003864CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003865 if (clang_isInvalid(C.kind))
3866 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003867
Ted Kremenek91554282010-11-16 08:15:36 +00003868 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003869
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003870 bool WasReference = false;
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003871 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003872 C = clang_getCursorReferenced(C);
3873 WasReference = true;
3874 }
3875
Douglas Gregor78ae2482010-03-18 18:23:03 +00003876 if (C.kind == CXCursor_MacroInstantiation)
3877 return clang_getCursorReferenced(C);
3878
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003879 if (!clang_isDeclaration(C.kind))
3880 return clang_getNullCursor();
3881
3882 Decl *D = getCursorDecl(C);
3883 if (!D)
3884 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003885
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003886 switch (D->getKind()) {
3887 // Declaration kinds that don't really separate the notions of
3888 // declaration and definition.
3889 case Decl::Namespace:
3890 case Decl::Typedef:
Richard Smithdda56e42011-04-15 14:24:37 +00003891 case Decl::TypeAlias:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003892 case Decl::TemplateTypeParm:
3893 case Decl::EnumConstant:
3894 case Decl::Field:
Benjamin Kramer39593702010-11-21 14:11:41 +00003895 case Decl::IndirectField:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003896 case Decl::ObjCIvar:
3897 case Decl::ObjCAtDefsField:
3898 case Decl::ImplicitParam:
3899 case Decl::ParmVar:
3900 case Decl::NonTypeTemplateParm:
3901 case Decl::TemplateTemplateParm:
3902 case Decl::ObjCCategoryImpl:
3903 case Decl::ObjCImplementation:
Abramo Bagnarad7340582010-06-05 05:09:32 +00003904 case Decl::AccessSpec:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003905 case Decl::LinkageSpec:
3906 case Decl::ObjCPropertyImpl:
3907 case Decl::FileScopeAsm:
3908 case Decl::StaticAssert:
3909 case Decl::Block:
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003910 case Decl::Label: // FIXME: Is this right??
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003911 return C;
3912
3913 // Declaration kinds that don't make any sense here, but are
3914 // nonetheless harmless.
3915 case Decl::TranslationUnit:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003916 break;
3917
3918 // Declaration kinds for which the definition is not resolvable.
3919 case Decl::UnresolvedUsingTypename:
3920 case Decl::UnresolvedUsingValue:
3921 break;
3922
3923 case Decl::UsingDirective:
Douglas Gregorfed36b12010-01-20 23:57:43 +00003924 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremenek91554282010-11-16 08:15:36 +00003925 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003926
3927 case Decl::NamespaceAlias:
Ted Kremenek91554282010-11-16 08:15:36 +00003928 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003929
3930 case Decl::Enum:
3931 case Decl::Record:
3932 case Decl::CXXRecord:
3933 case Decl::ClassTemplateSpecialization:
3934 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003935 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003936 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003937 return clang_getNullCursor();
3938
3939 case Decl::Function:
3940 case Decl::CXXMethod:
3941 case Decl::CXXConstructor:
3942 case Decl::CXXDestructor:
3943 case Decl::CXXConversion: {
3944 const FunctionDecl *Def = 0;
3945 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003946 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003947 return clang_getNullCursor();
3948 }
3949
3950 case Decl::Var: {
Sebastian Redl5ca79842010-02-01 20:16:42 +00003951 // Ask the variable if it has a definition.
3952 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003953 return MakeCXCursor(Def, TU);
Sebastian Redl5ca79842010-02-01 20:16:42 +00003954 return clang_getNullCursor();
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003955 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003956
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003957 case Decl::FunctionTemplate: {
3958 const FunctionDecl *Def = 0;
3959 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003960 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003961 return clang_getNullCursor();
3962 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003963
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003964 case Decl::ClassTemplate: {
3965 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003966 ->getDefinition())
Douglas Gregora23e8f72010-08-31 20:37:03 +00003967 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremenek91554282010-11-16 08:15:36 +00003968 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003969 return clang_getNullCursor();
3970 }
3971
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003972 case Decl::Using:
3973 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00003974 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003975
3976 case Decl::UsingShadow:
3977 return clang_getCursorDefinition(
Ted Kremenekf441baf2010-02-17 00:41:40 +00003978 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremenek91554282010-11-16 08:15:36 +00003979 TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003980
3981 case Decl::ObjCMethod: {
3982 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3983 if (Method->isThisDeclarationADefinition())
3984 return C;
3985
3986 // Dig out the method definition in the associated
3987 // @implementation, if we have it.
3988 // FIXME: The ASTs should make finding the definition easier.
3989 if (ObjCInterfaceDecl *Class
3990 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3991 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3992 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3993 Method->isInstanceMethod()))
3994 if (Def->isThisDeclarationADefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003995 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003996
3997 return clang_getNullCursor();
3998 }
3999
4000 case Decl::ObjCCategory:
4001 if (ObjCCategoryImplDecl *Impl
4002 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00004003 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004004 return clang_getNullCursor();
4005
4006 case Decl::ObjCProtocol:
4007 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
4008 return C;
4009 return clang_getNullCursor();
4010
4011 case Decl::ObjCInterface:
4012 // There are two notions of a "definition" for an Objective-C
4013 // class: the interface and its implementation. When we resolved a
4014 // reference to an Objective-C class, produce the @interface as
4015 // the definition; when we were provided with the interface,
4016 // produce the @implementation as the definition.
4017 if (WasReference) {
4018 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4019 return C;
4020 } else if (ObjCImplementationDecl *Impl
4021 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00004022 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004023 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004024
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004025 case Decl::ObjCProperty:
4026 // FIXME: We don't really know where to find the
4027 // ObjCPropertyImplDecls that implement this property.
4028 return clang_getNullCursor();
4029
4030 case Decl::ObjCCompatibleAlias:
4031 if (ObjCInterfaceDecl *Class
4032 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4033 if (!Class->isForwardDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004034 return MakeCXCursor(Class, TU);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004035
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004036 return clang_getNullCursor();
4037
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004038 case Decl::ObjCForwardProtocol:
4039 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00004040 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004041
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004042 case Decl::ObjCClass:
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00004043 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremenek91554282010-11-16 08:15:36 +00004044 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004045
4046 case Decl::Friend:
4047 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004048 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004049 return clang_getNullCursor();
4050
4051 case Decl::FriendTemplate:
4052 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004053 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004054 return clang_getNullCursor();
4055 }
4056
4057 return clang_getNullCursor();
4058}
4059
4060unsigned clang_isCursorDefinition(CXCursor C) {
4061 if (!clang_isDeclaration(C.kind))
4062 return 0;
4063
4064 return clang_getCursorDefinition(C) == C;
4065}
4066
Douglas Gregorfec4dc92010-11-19 23:44:15 +00004067CXCursor clang_getCanonicalCursor(CXCursor C) {
4068 if (!clang_isDeclaration(C.kind))
4069 return C;
4070
4071 if (Decl *D = getCursorDecl(C))
4072 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4073
4074 return C;
4075}
4076
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004077unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregorae185302010-09-16 13:54:00 +00004078 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004079 return 0;
4080
4081 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4082 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4083 return E->getNumDecls();
4084
4085 if (OverloadedTemplateStorage *S
4086 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4087 return S->size();
4088
4089 Decl *D = Storage.get<Decl*>();
4090 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis2703beb2010-11-10 05:40:41 +00004091 return Using->shadow_size();
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004092 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4093 return Classes->size();
4094 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4095 return Protocols->protocol_size();
4096
4097 return 0;
4098}
4099
4100CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregorae185302010-09-16 13:54:00 +00004101 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004102 return clang_getNullCursor();
4103
4104 if (index >= clang_getNumOverloadedDecls(cursor))
4105 return clang_getNullCursor();
4106
Ted Kremenek91554282010-11-16 08:15:36 +00004107 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004108 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4109 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremenek91554282010-11-16 08:15:36 +00004110 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004111
4112 if (OverloadedTemplateStorage *S
4113 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremenek91554282010-11-16 08:15:36 +00004114 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004115
4116 Decl *D = Storage.get<Decl*>();
4117 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4118 // FIXME: This is, unfortunately, linear time.
4119 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4120 std::advance(Pos, index);
Ted Kremenek91554282010-11-16 08:15:36 +00004121 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004122 }
4123
4124 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004125 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004126
4127 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004128 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004129
4130 return clang_getNullCursor();
4131}
4132
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00004133void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff76b8f132009-09-23 17:52:52 +00004134 const char **startBuf,
4135 const char **endBuf,
4136 unsigned *startLine,
4137 unsigned *startColumn,
4138 unsigned *endLine,
Daniel Dunbar079203f2009-12-01 03:14:51 +00004139 unsigned *endColumn) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00004140 assert(getCursorDecl(C) && "CXCursor has null decl");
4141 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff76b8f132009-09-23 17:52:52 +00004142 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4143 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004144
Steve Naroff76b8f132009-09-23 17:52:52 +00004145 SourceManager &SM = FD->getASTContext().getSourceManager();
4146 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4147 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4148 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4149 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4150 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4151 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4152}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004153
Douglas Gregor1e21cc72010-02-18 23:07:20 +00004154void clang_enableStackTraces(void) {
4155 llvm::sys::PrintStackTraceOnErrorSignal();
4156}
4157
Daniel Dunbar23420652010-11-04 01:26:29 +00004158void clang_executeOnThread(void (*fn)(void*), void *user_data,
4159 unsigned stack_size) {
4160 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4161}
4162
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004163} // end: extern "C"
Steve Naroff76b8f132009-09-23 17:52:52 +00004164
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004165//===----------------------------------------------------------------------===//
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004166// Token-based Operations.
4167//===----------------------------------------------------------------------===//
4168
4169/* CXToken layout:
4170 * int_data[0]: a CXTokenKind
4171 * int_data[1]: starting token location
4172 * int_data[2]: token length
4173 * int_data[3]: reserved
Ted Kremenekf441baf2010-02-17 00:41:40 +00004174 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004175 * otherwise unused.
4176 */
4177extern "C" {
4178
4179CXTokenKind clang_getTokenKind(CXToken CXTok) {
4180 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4181}
4182
4183CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4184 switch (clang_getTokenKind(CXTok)) {
4185 case CXToken_Identifier:
4186 case CXToken_Keyword:
4187 // We know we have an IdentifierInfo*, so use that.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004188 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4189 ->getNameStart());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004190
4191 case CXToken_Literal: {
4192 // We have stashed the starting pointer in the ptr_data field. Use it.
4193 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004194 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004195 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004196
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004197 case CXToken_Punctuation:
4198 case CXToken_Comment:
4199 break;
4200 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004201
4202 // We have to find the starting buffer pointer the hard way, by
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004203 // deconstructing the source location.
Ted Kremenek91554282010-11-16 08:15:36 +00004204 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004205 if (!CXXUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004206 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00004207
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004208 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4209 std::pair<FileID, unsigned> LocInfo
4210 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregore0fbb832010-03-16 00:06:06 +00004211 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004212 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004213 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4214 if (Invalid)
Douglas Gregor802b7762010-03-15 22:54:52 +00004215 return createCXString("");
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004216
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004217 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004218}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004219
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004220CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
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)
4223 return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004224
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004225 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4226 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4227}
4228
4229CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004230 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4f9c3762010-01-28 00:27:43 +00004231 if (!CXXUnit)
4232 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004233
4234 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004235 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4236}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004237
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004238void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4239 CXToken **Tokens, unsigned *NumTokens) {
4240 if (Tokens)
4241 *Tokens = 0;
4242 if (NumTokens)
4243 *NumTokens = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004244
Ted Kremenek91554282010-11-16 08:15:36 +00004245 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004246 if (!CXXUnit || !Tokens || !NumTokens)
4247 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004248
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004249 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4250
Daniel Dunbar80daf532010-02-14 08:31:57 +00004251 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004252 if (R.isInvalid())
4253 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004254
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004255 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4256 std::pair<FileID, unsigned> BeginLocInfo
4257 = SourceMgr.getDecomposedLoc(R.getBegin());
4258 std::pair<FileID, unsigned> EndLocInfo
4259 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004260
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004261 // Cannot tokenize across files.
4262 if (BeginLocInfo.first != EndLocInfo.first)
4263 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004264
4265 // Create a lexer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004266 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004267 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004268 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor554e0b12010-03-16 20:26:15 +00004269 if (Invalid)
4270 return;
Douglas Gregor802b7762010-03-15 22:54:52 +00004271
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004272 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4273 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004274 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004275 Lex.SetCommentRetentionState(true);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004276
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004277 // Lex tokens until we hit the end of the range.
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004278 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004279 llvm::SmallVector<CXToken, 32> CXTokens;
4280 Token Tok;
David Chisnall1822d1f2010-10-13 21:44:48 +00004281 bool previousWasAt = false;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004282 do {
4283 // Lex the next token
4284 Lex.LexFromRawLexer(Tok);
4285 if (Tok.is(tok::eof))
4286 break;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004287
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004288 // Initialize the CXToken.
4289 CXToken CXTok;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004290
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004291 // - Common fields
4292 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4293 CXTok.int_data[2] = Tok.getLength();
4294 CXTok.int_data[3] = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004295
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004296 // - Kind-specific fields
4297 if (Tok.isLiteral()) {
4298 CXTok.int_data[0] = CXToken_Literal;
4299 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004300 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregor802b7762010-03-15 22:54:52 +00004301 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004302 IdentifierInfo *II
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004303 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004304
David Chisnall1822d1f2010-10-13 21:44:48 +00004305 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004306 CXTok.int_data[0] = CXToken_Keyword;
4307 }
4308 else {
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004309 CXTok.int_data[0] = Tok.is(tok::identifier)
4310 ? CXToken_Identifier
4311 : CXToken_Keyword;
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004312 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004313 CXTok.ptr_data = II;
4314 } else if (Tok.is(tok::comment)) {
4315 CXTok.int_data[0] = CXToken_Comment;
4316 CXTok.ptr_data = 0;
4317 } else {
4318 CXTok.int_data[0] = CXToken_Punctuation;
4319 CXTok.ptr_data = 0;
4320 }
4321 CXTokens.push_back(CXTok);
David Chisnall1822d1f2010-10-13 21:44:48 +00004322 previousWasAt = Tok.is(tok::at);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004323 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004324
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004325 if (CXTokens.empty())
4326 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004327
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004328 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4329 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4330 *NumTokens = CXTokens.size();
4331}
Douglas Gregor61656112010-01-26 18:31:56 +00004332
Ted Kremenek63ac5992010-05-05 00:55:15 +00004333void clang_disposeTokens(CXTranslationUnit TU,
4334 CXToken *Tokens, unsigned NumTokens) {
4335 free(Tokens);
4336}
4337
4338} // end: extern "C"
4339
4340//===----------------------------------------------------------------------===//
4341// Token annotation APIs.
4342//===----------------------------------------------------------------------===//
4343
Douglas Gregor61656112010-01-26 18:31:56 +00004344typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenek680fe512010-05-05 00:55:23 +00004345static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4346 CXCursor parent,
4347 CXClientData client_data);
Ted Kremenek63ac5992010-05-05 00:55:15 +00004348namespace {
4349class AnnotateTokensWorker {
4350 AnnotateTokensData &Annotated;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004351 CXToken *Tokens;
4352 CXCursor *Cursors;
4353 unsigned NumTokens;
Ted Kremenek680fe512010-05-05 00:55:23 +00004354 unsigned TokIdx;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004355 unsigned PreprocessingTokIdx;
Ted Kremenek680fe512010-05-05 00:55:23 +00004356 CursorVisitor AnnotateVis;
4357 SourceManager &SrcMgr;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004358 bool HasContextSensitiveKeywords;
4359
Ted Kremenek680fe512010-05-05 00:55:23 +00004360 bool MoreTokens() const { return TokIdx < NumTokens; }
4361 unsigned NextToken() const { return TokIdx; }
4362 void AdvanceToken() { ++TokIdx; }
4363 SourceLocation GetTokenLoc(unsigned tokI) {
4364 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4365 }
4366
Ted Kremenek63ac5992010-05-05 00:55:15 +00004367public:
Ted Kremenek458c2f12010-05-05 00:55:17 +00004368 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenek680fe512010-05-05 00:55:23 +00004369 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremenek91554282010-11-16 08:15:36 +00004370 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek458c2f12010-05-05 00:55:17 +00004371 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004372 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremenek91554282010-11-16 08:15:36 +00004373 AnnotateVis(tu,
4374 AnnotateTokensVisitor, this,
Douglas Gregorc2b97992011-03-16 23:23:30 +00004375 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf2f08062011-03-08 17:10:18 +00004376 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4377 HasContextSensitiveKeywords(false) { }
Ted Kremenek458c2f12010-05-05 00:55:17 +00004378
Ted Kremenek680fe512010-05-05 00:55:23 +00004379 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004380 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenek680fe512010-05-05 00:55:23 +00004381 void AnnotateTokens(CXCursor parent);
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004382 void AnnotateTokens() {
Ted Kremenek91554282010-11-16 08:15:36 +00004383 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004384 }
Douglas Gregorf2f08062011-03-08 17:10:18 +00004385
4386 /// \brief Determine whether the annotator saw any cursors that have
4387 /// context-sensitive keywords.
4388 bool hasContextSensitiveKeywords() const {
4389 return HasContextSensitiveKeywords;
4390 }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004391};
4392}
Douglas Gregor61656112010-01-26 18:31:56 +00004393
Ted Kremenek680fe512010-05-05 00:55:23 +00004394void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4395 // Walk the AST within the region of interest, annotating tokens
4396 // along the way.
4397 VisitChildren(parent);
Ted Kremenek458c2f12010-05-05 00:55:17 +00004398
Ted Kremenek680fe512010-05-05 00:55:23 +00004399 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4400 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004401 if (Pos != Annotated.end() &&
4402 (clang_isInvalid(Cursors[I].kind) ||
4403 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenek680fe512010-05-05 00:55:23 +00004404 Cursors[I] = Pos->second;
4405 }
4406
4407 // Finish up annotating any tokens left.
4408 if (!MoreTokens())
4409 return;
4410
4411 const CXCursor &C = clang_getNullCursor();
4412 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4413 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4414 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004415 }
4416}
4417
Ted Kremenek63ac5992010-05-05 00:55:15 +00004418enum CXChildVisitResult
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004419AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004420 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004421 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004422 if (cursorRange.isInvalid())
4423 return CXChildVisit_Recurse;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004424
4425 if (!HasContextSensitiveKeywords) {
4426 // Objective-C properties can have context-sensitive keywords.
4427 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4428 if (ObjCPropertyDecl *Property
4429 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4430 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4431 }
4432 // Objective-C methods can have context-sensitive keywords.
4433 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4434 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4435 if (ObjCMethodDecl *Method
4436 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4437 if (Method->getObjCDeclQualifier())
4438 HasContextSensitiveKeywords = true;
4439 else {
4440 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4441 PEnd = Method->param_end();
4442 P != PEnd; ++P) {
4443 if ((*P)->getObjCDeclQualifier()) {
4444 HasContextSensitiveKeywords = true;
4445 break;
4446 }
4447 }
4448 }
4449 }
4450 }
4451 // C++ methods can have context-sensitive keywords.
4452 else if (cursor.kind == CXCursor_CXXMethod) {
4453 if (CXXMethodDecl *Method
4454 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4455 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4456 HasContextSensitiveKeywords = true;
4457 }
4458 }
4459 // C++ classes can have context-sensitive keywords.
4460 else if (cursor.kind == CXCursor_StructDecl ||
4461 cursor.kind == CXCursor_ClassDecl ||
4462 cursor.kind == CXCursor_ClassTemplate ||
4463 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4464 if (Decl *D = getCursorDecl(cursor))
4465 if (D->hasAttr<FinalAttr>())
4466 HasContextSensitiveKeywords = true;
4467 }
4468 }
4469
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004470 if (clang_isPreprocessing(cursor.kind)) {
4471 // For macro instantiations, just note where the beginning of the macro
4472 // instantiation occurs.
4473 if (cursor.kind == CXCursor_MacroInstantiation) {
4474 Annotated[Loc.int_data] = cursor;
4475 return CXChildVisit_Recurse;
4476 }
4477
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004478 // Items in the preprocessing record are kept separate from items in
4479 // declarations, so we keep a separate token index.
4480 unsigned SavedTokIdx = TokIdx;
4481 TokIdx = PreprocessingTokIdx;
4482
4483 // Skip tokens up until we catch up to the beginning of the preprocessing
4484 // entry.
4485 while (MoreTokens()) {
4486 const unsigned I = NextToken();
4487 SourceLocation TokLoc = GetTokenLoc(I);
4488 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4489 case RangeBefore:
4490 AdvanceToken();
4491 continue;
4492 case RangeAfter:
4493 case RangeOverlap:
4494 break;
4495 }
4496 break;
4497 }
4498
4499 // Look at all of the tokens within this range.
4500 while (MoreTokens()) {
4501 const unsigned I = NextToken();
4502 SourceLocation TokLoc = GetTokenLoc(I);
4503 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4504 case RangeBefore:
4505 assert(0 && "Infeasible");
4506 case RangeAfter:
4507 break;
4508 case RangeOverlap:
4509 Cursors[I] = cursor;
4510 AdvanceToken();
4511 continue;
4512 }
4513 break;
4514 }
4515
4516 // Save the preprocessing token index; restore the non-preprocessing
4517 // token index.
4518 PreprocessingTokIdx = TokIdx;
4519 TokIdx = SavedTokIdx;
Douglas Gregor61656112010-01-26 18:31:56 +00004520 return CXChildVisit_Recurse;
4521 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004522
Ted Kremenek680fe512010-05-05 00:55:23 +00004523 if (cursorRange.isInvalid())
4524 return CXChildVisit_Continue;
Ted Kremenek5d616142010-05-12 05:29:33 +00004525
Ted Kremenek680fe512010-05-05 00:55:23 +00004526 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4527
Ted Kremenek5d616142010-05-12 05:29:33 +00004528 // Adjust the annotated range based specific declarations.
4529 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4530 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek49be9e02010-05-18 21:09:07 +00004531 Decl *D = cxcursor::getCursorDecl(cursor);
4532 // Don't visit synthesized ObjC methods, since they have no syntatic
4533 // representation in the source.
4534 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4535 if (MD->isSynthesized())
4536 return CXChildVisit_Continue;
4537 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004538
4539 SourceLocation StartLoc;
Ted Kremenek49be9e02010-05-18 21:09:07 +00004540 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004541 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4542 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4543 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4544 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4545 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremenek5d616142010-05-12 05:29:33 +00004546 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004547
4548 if (StartLoc.isValid() && L.isValid() &&
4549 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4550 cursorRange.setBegin(StartLoc);
Ted Kremenek5d616142010-05-12 05:29:33 +00004551 }
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004552
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004553 // If the location of the cursor occurs within a macro instantiation, record
4554 // the spelling location of the cursor in our annotation map. We can then
4555 // paper over the token labelings during a post-processing step to try and
4556 // get cursor mappings for tokens that are the *arguments* of a macro
4557 // instantiation.
4558 if (L.isMacroID()) {
4559 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4560 // Only invalidate the old annotation if it isn't part of a preprocessing
4561 // directive. Here we assume that the default construction of CXCursor
4562 // results in CXCursor.kind being an initialized value (i.e., 0). If
4563 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004564
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004565 CXCursor &oldC = Annotated[rawEncoding];
4566 if (!clang_isPreprocessing(oldC.kind))
4567 oldC = cursor;
4568 }
4569
Ted Kremenek680fe512010-05-05 00:55:23 +00004570 const enum CXCursorKind K = clang_getCursorKind(parent);
4571 const CXCursor updateC =
Ted Kremenek65b2cc02010-08-25 22:16:02 +00004572 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4573 ? clang_getNullCursor() : parent;
Ted Kremenek680fe512010-05-05 00:55:23 +00004574
4575 while (MoreTokens()) {
4576 const unsigned I = NextToken();
4577 SourceLocation TokLoc = GetTokenLoc(I);
4578 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4579 case RangeBefore:
4580 Cursors[I] = updateC;
4581 AdvanceToken();
4582 continue;
4583 case RangeAfter:
Ted Kremenek680fe512010-05-05 00:55:23 +00004584 case RangeOverlap:
4585 break;
4586 }
4587 break;
4588 }
4589
4590 // Visit children to get their cursor information.
4591 const unsigned BeforeChildren = NextToken();
4592 VisitChildren(cursor);
4593 const unsigned AfterChildren = NextToken();
4594
4595 // Adjust 'Last' to the last token within the extent of the cursor.
4596 while (MoreTokens()) {
4597 const unsigned I = NextToken();
4598 SourceLocation TokLoc = GetTokenLoc(I);
4599 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4600 case RangeBefore:
4601 assert(0 && "Infeasible");
4602 case RangeAfter:
4603 break;
4604 case RangeOverlap:
4605 Cursors[I] = updateC;
4606 AdvanceToken();
4607 continue;
4608 }
4609 break;
4610 }
4611 const unsigned Last = NextToken();
Ted Kremenek63ac5992010-05-05 00:55:15 +00004612
Ted Kremenek680fe512010-05-05 00:55:23 +00004613 // Scan the tokens that are at the beginning of the cursor, but are not
4614 // capture by the child cursors.
4615
4616 // For AST elements within macros, rely on a post-annotate pass to
4617 // to correctly annotate the tokens with cursors. Otherwise we can
4618 // get confusing results of having tokens that map to cursors that really
4619 // are expanded by an instantiation.
4620 if (L.isMacroID())
4621 cursor = clang_getNullCursor();
4622
4623 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4624 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4625 break;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004626
Ted Kremenek680fe512010-05-05 00:55:23 +00004627 Cursors[I] = cursor;
4628 }
4629 // Scan the tokens that are at the end of the cursor, but are not captured
4630 // but the child cursors.
4631 for (unsigned I = AfterChildren; I != Last; ++I)
4632 Cursors[I] = cursor;
4633
4634 TokIdx = Last;
4635 return CXChildVisit_Continue;
Douglas Gregor61656112010-01-26 18:31:56 +00004636}
4637
Ted Kremenek63ac5992010-05-05 00:55:15 +00004638static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4639 CXCursor parent,
4640 CXClientData client_data) {
4641 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4642}
4643
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004644namespace {
4645 struct clang_annotateTokens_Data {
4646 CXTranslationUnit TU;
4647 ASTUnit *CXXUnit;
4648 CXToken *Tokens;
4649 unsigned NumTokens;
4650 CXCursor *Cursors;
4651 };
4652}
4653
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004654// This gets run a separate thread to avoid stack blowout.
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004655static void clang_annotateTokensImpl(void *UserData) {
4656 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4657 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4658 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4659 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4660 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4661
4662 // Determine the region of interest, which contains all of the tokens.
4663 SourceRange RegionOfInterest;
4664 RegionOfInterest.setBegin(
4665 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4666 RegionOfInterest.setEnd(
4667 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4668 Tokens[NumTokens-1])));
4669
4670 // A mapping from the source locations found when re-lexing or traversing the
4671 // region of interest to the corresponding cursors.
4672 AnnotateTokensData Annotated;
4673
4674 // Relex the tokens within the source range to look for preprocessing
4675 // directives.
4676 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4677 std::pair<FileID, unsigned> BeginLocInfo
4678 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4679 std::pair<FileID, unsigned> EndLocInfo
4680 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4681
4682 llvm::StringRef Buffer;
4683 bool Invalid = false;
4684 if (BeginLocInfo.first == EndLocInfo.first &&
4685 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4686 !Invalid) {
4687 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4688 CXXUnit->getASTContext().getLangOptions(),
4689 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4690 Buffer.end());
4691 Lex.SetCommentRetentionState(true);
4692
4693 // Lex tokens in raw mode until we hit the end of the range, to avoid
4694 // entering #includes or expanding macros.
4695 while (true) {
4696 Token Tok;
4697 Lex.LexFromRawLexer(Tok);
4698
4699 reprocess:
4700 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4701 // We have found a preprocessing directive. Gobble it up so that we
4702 // don't see it while preprocessing these tokens later, but keep track
4703 // of all of the token locations inside this preprocessing directive so
4704 // that we can annotate them appropriately.
4705 //
4706 // FIXME: Some simple tests here could identify macro definitions and
4707 // #undefs, to provide specific cursor kinds for those.
4708 llvm::SmallVector<SourceLocation, 32> Locations;
4709 do {
4710 Locations.push_back(Tok.getLocation());
4711 Lex.LexFromRawLexer(Tok);
4712 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4713
4714 using namespace cxcursor;
4715 CXCursor Cursor
4716 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4717 Locations.back()),
4718 TU);
4719 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4720 Annotated[Locations[I].getRawEncoding()] = Cursor;
4721 }
4722
4723 if (Tok.isAtStartOfLine())
4724 goto reprocess;
4725
4726 continue;
4727 }
4728
4729 if (Tok.is(tok::eof))
4730 break;
4731 }
4732 }
4733
4734 // Annotate all of the source locations in the region of interest that map to
4735 // a specific cursor.
4736 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4737 TU, RegionOfInterest);
4738
4739 // FIXME: We use a ridiculous stack size here because the data-recursion
4740 // algorithm uses a large stack frame than the non-data recursive version,
4741 // and AnnotationTokensWorker currently transforms the data-recursion
4742 // algorithm back into a traditional recursion by explicitly calling
4743 // VisitChildren(). We will need to remove this explicit recursive call.
4744 W.AnnotateTokens();
4745
4746 // If we ran into any entities that involve context-sensitive keywords,
4747 // take another pass through the tokens to mark them as such.
4748 if (W.hasContextSensitiveKeywords()) {
4749 for (unsigned I = 0; I != NumTokens; ++I) {
4750 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4751 continue;
4752
4753 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4754 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4755 if (ObjCPropertyDecl *Property
4756 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4757 if (Property->getPropertyAttributesAsWritten() != 0 &&
4758 llvm::StringSwitch<bool>(II->getName())
4759 .Case("readonly", true)
4760 .Case("assign", true)
4761 .Case("readwrite", true)
4762 .Case("retain", true)
4763 .Case("copy", true)
4764 .Case("nonatomic", true)
4765 .Case("atomic", true)
4766 .Case("getter", true)
4767 .Case("setter", true)
4768 .Default(false))
4769 Tokens[I].int_data[0] = CXToken_Keyword;
4770 }
4771 continue;
4772 }
4773
4774 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4775 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4776 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4777 if (llvm::StringSwitch<bool>(II->getName())
4778 .Case("in", true)
4779 .Case("out", true)
4780 .Case("inout", true)
4781 .Case("oneway", true)
4782 .Case("bycopy", true)
4783 .Case("byref", true)
4784 .Default(false))
4785 Tokens[I].int_data[0] = CXToken_Keyword;
4786 continue;
4787 }
4788
4789 if (Cursors[I].kind == CXCursor_CXXMethod) {
4790 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4791 if (CXXMethodDecl *Method
4792 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4793 if ((Method->hasAttr<FinalAttr>() ||
4794 Method->hasAttr<OverrideAttr>()) &&
4795 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4796 llvm::StringSwitch<bool>(II->getName())
4797 .Case("final", true)
4798 .Case("override", true)
4799 .Default(false))
4800 Tokens[I].int_data[0] = CXToken_Keyword;
4801 }
4802 continue;
4803 }
4804
4805 if (Cursors[I].kind == CXCursor_ClassDecl ||
4806 Cursors[I].kind == CXCursor_StructDecl ||
4807 Cursors[I].kind == CXCursor_ClassTemplate) {
4808 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4809 if (II->getName() == "final") {
4810 // We have to be careful with 'final', since it could be the name
4811 // of a member class rather than the context-sensitive keyword.
4812 // So, check whether the cursor associated with this
4813 Decl *D = getCursorDecl(Cursors[I]);
4814 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4815 if ((Record->hasAttr<FinalAttr>()) &&
4816 Record->getIdentifier() != II)
4817 Tokens[I].int_data[0] = CXToken_Keyword;
4818 } else if (ClassTemplateDecl *ClassTemplate
4819 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4820 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4821 if ((Record->hasAttr<FinalAttr>()) &&
4822 Record->getIdentifier() != II)
4823 Tokens[I].int_data[0] = CXToken_Keyword;
4824 }
4825 }
4826 continue;
4827 }
4828 }
4829 }
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004830}
4831
Ted Kremenek63ac5992010-05-05 00:55:15 +00004832extern "C" {
4833
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004834void clang_annotateTokens(CXTranslationUnit TU,
4835 CXToken *Tokens, unsigned NumTokens,
4836 CXCursor *Cursors) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004837
4838 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor61656112010-01-26 18:31:56 +00004839 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004840
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004841 // Any token we don't specifically annotate will have a NULL cursor.
4842 CXCursor C = clang_getNullCursor();
4843 for (unsigned I = 0; I != NumTokens; ++I)
4844 Cursors[I] = C;
4845
Ted Kremenek91554282010-11-16 08:15:36 +00004846 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004847 if (!CXXUnit)
Douglas Gregor61656112010-01-26 18:31:56 +00004848 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004849
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004850 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004851
4852 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004853 llvm::CrashRecoveryContext CRC;
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004854 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenekca817a3c2010-11-14 17:47:35 +00004855 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004856 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4857 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004858}
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004859
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004860} // end: extern "C"
4861
4862//===----------------------------------------------------------------------===//
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004863// Operations for querying linkage of a cursor.
4864//===----------------------------------------------------------------------===//
4865
4866extern "C" {
4867CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor5272e802010-03-19 05:22:59 +00004868 if (!clang_isDeclaration(cursor.kind))
4869 return CXLinkage_Invalid;
4870
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004871 Decl *D = cxcursor::getCursorDecl(cursor);
4872 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4873 switch (ND->getLinkage()) {
4874 case NoLinkage: return CXLinkage_NoLinkage;
4875 case InternalLinkage: return CXLinkage_Internal;
4876 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4877 case ExternalLinkage: return CXLinkage_External;
4878 };
4879
4880 return CXLinkage_Invalid;
4881}
4882} // end: extern "C"
4883
4884//===----------------------------------------------------------------------===//
Ted Kremenek4ed29252010-04-12 21:22:16 +00004885// Operations for querying language of a cursor.
4886//===----------------------------------------------------------------------===//
4887
4888static CXLanguageKind getDeclLanguage(const Decl *D) {
4889 switch (D->getKind()) {
4890 default:
4891 break;
4892 case Decl::ImplicitParam:
4893 case Decl::ObjCAtDefsField:
4894 case Decl::ObjCCategory:
4895 case Decl::ObjCCategoryImpl:
4896 case Decl::ObjCClass:
4897 case Decl::ObjCCompatibleAlias:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004898 case Decl::ObjCForwardProtocol:
4899 case Decl::ObjCImplementation:
4900 case Decl::ObjCInterface:
4901 case Decl::ObjCIvar:
4902 case Decl::ObjCMethod:
4903 case Decl::ObjCProperty:
4904 case Decl::ObjCPropertyImpl:
4905 case Decl::ObjCProtocol:
4906 return CXLanguage_ObjC;
4907 case Decl::CXXConstructor:
4908 case Decl::CXXConversion:
4909 case Decl::CXXDestructor:
4910 case Decl::CXXMethod:
4911 case Decl::CXXRecord:
4912 case Decl::ClassTemplate:
4913 case Decl::ClassTemplatePartialSpecialization:
4914 case Decl::ClassTemplateSpecialization:
4915 case Decl::Friend:
4916 case Decl::FriendTemplate:
4917 case Decl::FunctionTemplate:
4918 case Decl::LinkageSpec:
4919 case Decl::Namespace:
4920 case Decl::NamespaceAlias:
4921 case Decl::NonTypeTemplateParm:
4922 case Decl::StaticAssert:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004923 case Decl::TemplateTemplateParm:
4924 case Decl::TemplateTypeParm:
4925 case Decl::UnresolvedUsingTypename:
4926 case Decl::UnresolvedUsingValue:
4927 case Decl::Using:
4928 case Decl::UsingDirective:
4929 case Decl::UsingShadow:
4930 return CXLanguage_CPlusPlus;
4931 }
4932
4933 return CXLanguage_C;
4934}
4935
4936extern "C" {
Douglas Gregorf757a122010-08-23 23:00:57 +00004937
4938enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4939 if (clang_isDeclaration(cursor.kind))
4940 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004941 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregorf757a122010-08-23 23:00:57 +00004942 return CXAvailability_Available;
4943
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004944 switch (D->getAvailability()) {
4945 case AR_Available:
4946 case AR_NotYetIntroduced:
4947 return CXAvailability_Available;
4948
4949 case AR_Deprecated:
Douglas Gregorf757a122010-08-23 23:00:57 +00004950 return CXAvailability_Deprecated;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004951
4952 case AR_Unavailable:
4953 return CXAvailability_NotAvailable;
4954 }
Douglas Gregorf757a122010-08-23 23:00:57 +00004955 }
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004956
Douglas Gregorf757a122010-08-23 23:00:57 +00004957 return CXAvailability_Available;
4958}
4959
Ted Kremenek4ed29252010-04-12 21:22:16 +00004960CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4961 if (clang_isDeclaration(cursor.kind))
4962 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4963
4964 return CXLanguage_Invalid;
4965}
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004966
4967 /// \brief If the given cursor is the "templated" declaration
4968 /// descibing a class or function template, return the class or
4969 /// function template.
4970static Decl *maybeGetTemplateCursor(Decl *D) {
4971 if (!D)
4972 return 0;
4973
4974 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4975 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4976 return FunTmpl;
4977
4978 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4979 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4980 return ClassTmpl;
4981
4982 return D;
4983}
4984
Douglas Gregor0576ce72010-09-22 21:22:29 +00004985CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4986 if (clang_isDeclaration(cursor.kind)) {
4987 if (Decl *D = getCursorDecl(cursor)) {
4988 DeclContext *DC = D->getDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004989 if (!DC)
4990 return clang_getNullCursor();
4991
4992 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4993 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004994 }
4995 }
4996
4997 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4998 if (Decl *D = getCursorDecl(cursor))
Ted Kremenek91554282010-11-16 08:15:36 +00004999 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00005000 }
5001
5002 return clang_getNullCursor();
5003}
5004
5005CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5006 if (clang_isDeclaration(cursor.kind)) {
5007 if (Decl *D = getCursorDecl(cursor)) {
5008 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00005009 if (!DC)
5010 return clang_getNullCursor();
5011
5012 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5013 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00005014 }
5015 }
5016
5017 // FIXME: Note that we can't easily compute the lexical context of a
5018 // statement or expression, so we return nothing.
5019 return clang_getNullCursor();
5020}
5021
Douglas Gregor99a26af2010-10-01 20:25:15 +00005022static void CollectOverriddenMethods(DeclContext *Ctx,
5023 ObjCMethodDecl *Method,
5024 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5025 if (!Ctx)
5026 return;
5027
5028 // If we have a class or category implementation, jump straight to the
5029 // interface.
5030 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5031 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5032
5033 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5034 if (!Container)
5035 return;
5036
5037 // Check whether we have a matching method at this level.
5038 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5039 Method->isInstanceMethod()))
5040 if (Method != Overridden) {
5041 // We found an override at this level; there is no need to look
5042 // into other protocols or categories.
5043 Methods.push_back(Overridden);
5044 return;
5045 }
5046
5047 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5048 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5049 PEnd = Protocol->protocol_end();
5050 P != PEnd; ++P)
5051 CollectOverriddenMethods(*P, Method, Methods);
5052 }
5053
5054 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5055 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5056 PEnd = Category->protocol_end();
5057 P != PEnd; ++P)
5058 CollectOverriddenMethods(*P, Method, Methods);
5059 }
5060
5061 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5062 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5063 PEnd = Interface->protocol_end();
5064 P != PEnd; ++P)
5065 CollectOverriddenMethods(*P, Method, Methods);
5066
5067 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5068 Category; Category = Category->getNextClassCategory())
5069 CollectOverriddenMethods(Category, Method, Methods);
5070
5071 // We only look into the superclass if we haven't found anything yet.
5072 if (Methods.empty())
5073 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5074 return CollectOverriddenMethods(Super, Method, Methods);
5075 }
5076}
5077
5078void clang_getOverriddenCursors(CXCursor cursor,
5079 CXCursor **overridden,
5080 unsigned *num_overridden) {
5081 if (overridden)
5082 *overridden = 0;
5083 if (num_overridden)
5084 *num_overridden = 0;
5085 if (!overridden || !num_overridden)
5086 return;
5087
5088 if (!clang_isDeclaration(cursor.kind))
5089 return;
5090
5091 Decl *D = getCursorDecl(cursor);
5092 if (!D)
5093 return;
5094
5095 // Handle C++ member functions.
Ted Kremenek91554282010-11-16 08:15:36 +00005096 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005097 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5098 *num_overridden = CXXMethod->size_overridden_methods();
5099 if (!*num_overridden)
5100 return;
5101
5102 *overridden = new CXCursor [*num_overridden];
5103 unsigned I = 0;
5104 for (CXXMethodDecl::method_iterator
5105 M = CXXMethod->begin_overridden_methods(),
5106 MEnd = CXXMethod->end_overridden_methods();
5107 M != MEnd; (void)++M, ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00005108 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005109 return;
5110 }
5111
5112 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5113 if (!Method)
5114 return;
5115
5116 // Handle Objective-C methods.
5117 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5118 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5119
5120 if (Methods.empty())
5121 return;
5122
5123 *num_overridden = Methods.size();
5124 *overridden = new CXCursor [Methods.size()];
5125 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00005126 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005127}
5128
5129void clang_disposeOverriddenCursors(CXCursor *overridden) {
5130 delete [] overridden;
5131}
5132
Douglas Gregor796d76a2010-10-20 22:00:55 +00005133CXFile clang_getIncludedFile(CXCursor cursor) {
5134 if (cursor.kind != CXCursor_InclusionDirective)
5135 return 0;
5136
5137 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5138 return (void *)ID->getFile();
5139}
5140
Ted Kremenek4ed29252010-04-12 21:22:16 +00005141} // end: extern "C"
5142
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005143
5144//===----------------------------------------------------------------------===//
5145// C++ AST instrospection.
5146//===----------------------------------------------------------------------===//
5147
5148extern "C" {
5149unsigned clang_CXXMethod_isStatic(CXCursor C) {
5150 if (!clang_isDeclaration(C.kind))
5151 return 0;
Douglas Gregorf11309e2010-08-31 22:12:17 +00005152
5153 CXXMethodDecl *Method = 0;
5154 Decl *D = cxcursor::getCursorDecl(C);
5155 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5156 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5157 else
5158 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5159 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek0ed75492010-05-17 20:12:45 +00005160}
Ted Kremeneka10f1282010-05-18 22:32:15 +00005161
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005162} // end: extern "C"
5163
Ted Kremenek4ed29252010-04-12 21:22:16 +00005164//===----------------------------------------------------------------------===//
Ted Kremeneka5940822010-08-26 01:42:22 +00005165// Attribute introspection.
5166//===----------------------------------------------------------------------===//
5167
5168extern "C" {
5169CXType clang_getIBOutletCollectionType(CXCursor C) {
5170 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremenek91554282010-11-16 08:15:36 +00005171 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005172
5173 IBOutletCollectionAttr *A =
5174 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5175
Douglas Gregorc81a7a22011-03-06 18:55:32 +00005176 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005177}
5178} // end: extern "C"
5179
5180//===----------------------------------------------------------------------===//
Ted Kremenek83f642e2011-04-18 22:47:10 +00005181// Inspecting memory usage.
5182//===----------------------------------------------------------------------===//
5183
Ted Kremenek23324122011-04-20 16:41:07 +00005184typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
Ted Kremenek83f642e2011-04-18 22:47:10 +00005185
Ted Kremenek23324122011-04-20 16:41:07 +00005186static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
5187 enum CXTUResourceUsageKind k,
Ted Kremenek83f642e2011-04-18 22:47:10 +00005188 double amount) {
Ted Kremenek23324122011-04-20 16:41:07 +00005189 CXTUResourceUsageEntry entry = { k, amount };
Ted Kremenek83f642e2011-04-18 22:47:10 +00005190 entries.push_back(entry);
5191}
5192
5193extern "C" {
5194
Ted Kremenek23324122011-04-20 16:41:07 +00005195const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
Ted Kremenek83f642e2011-04-18 22:47:10 +00005196 const char *str = "";
5197 switch (kind) {
Ted Kremenek23324122011-04-20 16:41:07 +00005198 case CXTUResourceUsage_AST:
Ted Kremenek83f642e2011-04-18 22:47:10 +00005199 str = "ASTContext: expressions, declarations, and types";
5200 break;
Ted Kremenek23324122011-04-20 16:41:07 +00005201 case CXTUResourceUsage_Identifiers:
Ted Kremenek83f642e2011-04-18 22:47:10 +00005202 str = "ASTContext: identifiers";
5203 break;
Ted Kremenek23324122011-04-20 16:41:07 +00005204 case CXTUResourceUsage_Selectors:
Ted Kremenek83f642e2011-04-18 22:47:10 +00005205 str = "ASTContext: selectors";
Ted Kremenekfd07f852011-04-19 04:36:17 +00005206 break;
Ted Kremenek23324122011-04-20 16:41:07 +00005207 case CXTUResourceUsage_GlobalCompletionResults:
Ted Kremenek11d1a422011-04-18 23:42:53 +00005208 str = "Code completion: cached global results";
Ted Kremenekfd07f852011-04-19 04:36:17 +00005209 break;
Ted Kremenek83f642e2011-04-18 22:47:10 +00005210 }
5211 return str;
5212}
5213
Ted Kremenek23324122011-04-20 16:41:07 +00005214CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Ted Kremenek83f642e2011-04-18 22:47:10 +00005215 if (!TU) {
Ted Kremenek23324122011-04-20 16:41:07 +00005216 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
Ted Kremenek83f642e2011-04-18 22:47:10 +00005217 return usage;
5218 }
5219
5220 ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
5221 llvm::OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
5222 ASTContext &astContext = astUnit->getASTContext();
5223
5224 // How much memory is used by AST nodes and types?
Ted Kremenek23324122011-04-20 16:41:07 +00005225 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
Ted Kremenek83f642e2011-04-18 22:47:10 +00005226 (unsigned long) astContext.getTotalAllocatedMemory());
5227
5228 // How much memory is used by identifiers?
Ted Kremenek23324122011-04-20 16:41:07 +00005229 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
Ted Kremenek83f642e2011-04-18 22:47:10 +00005230 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
5231
5232 // How much memory is used for selectors?
Ted Kremenek23324122011-04-20 16:41:07 +00005233 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
Ted Kremenek83f642e2011-04-18 22:47:10 +00005234 (unsigned long) astContext.Selectors.getTotalMemory());
5235
Ted Kremenek11d1a422011-04-18 23:42:53 +00005236 // How much memory is used for caching global code completion results?
5237 unsigned long completionBytes = 0;
5238 if (GlobalCodeCompletionAllocator *completionAllocator =
5239 astUnit->getCachedCompletionAllocator().getPtr()) {
5240 completionBytes = completionAllocator-> getTotalMemory();
5241 }
Ted Kremenek23324122011-04-20 16:41:07 +00005242 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_GlobalCompletionResults,
Ted Kremenek11d1a422011-04-18 23:42:53 +00005243 completionBytes);
5244
5245
Ted Kremenek23324122011-04-20 16:41:07 +00005246 CXTUResourceUsage usage = { (void*) entries.get(),
Ted Kremenek83f642e2011-04-18 22:47:10 +00005247 (unsigned) entries->size(),
5248 entries->size() ? &(*entries)[0] : 0 };
5249 entries.take();
5250 return usage;
5251}
5252
Ted Kremenek23324122011-04-20 16:41:07 +00005253void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
Ted Kremenek83f642e2011-04-18 22:47:10 +00005254 if (usage.data)
5255 delete (MemUsageEntries*) usage.data;
5256}
5257
5258} // end extern "C"
5259
5260//===----------------------------------------------------------------------===//
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005261// Misc. utility functions.
5262//===----------------------------------------------------------------------===//
Ted Kremenekf441baf2010-02-17 00:41:40 +00005263
Daniel Dunbar087c3a32010-11-05 17:21:46 +00005264/// Default to using an 8 MB stack size on "safety" threads.
5265static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005266
5267namespace clang {
5268
5269bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenekca817a3c2010-11-14 17:47:35 +00005270 void (*Fn)(void*), void *UserData,
5271 unsigned Size) {
5272 if (!Size)
5273 Size = GetSafetyThreadStackSize();
5274 if (Size)
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005275 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5276 return CRC.RunSafely(Fn, UserData);
5277}
5278
5279unsigned GetSafetyThreadStackSize() {
5280 return SafetyStackThreadSize;
5281}
5282
5283void SetSafetyThreadStackSize(unsigned Value) {
5284 SafetyStackThreadSize = Value;
5285}
5286
5287}
5288
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005289extern "C" {
5290
Ted Kremeneka3e65702010-02-12 22:54:40 +00005291CXString clang_getClangVersion() {
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00005292 return createCXString(getClangFullVersion());
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005293}
5294
5295} // end: extern "C"
Ted Kremenek83f642e2011-04-18 22:47:10 +00005296