blob: f8ca13aab3283b64f324f315a652447b39d721aa [file] [log] [blame]
Ted Kremenekb60d87c2009-08-26 22:36:44 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00007//
Ted Kremenekb60d87c2009-08-26 22:36:44 +00008//===----------------------------------------------------------------------===//
9//
Ted Kremenek0ec2cca2010-01-05 19:32:54 +000010// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
Ted Kremenekb60d87c2009-08-26 22:36:44 +000012//
13//===----------------------------------------------------------------------===//
14
Ted Kremenek0ec2cca2010-01-05 19:32:54 +000015#include "CIndexer.h"
Ted Kremenek87553c42010-01-15 20:35:54 +000016#include "CXCursor.h"
Ted Kremenek7df92ae2010-11-17 23:24:11 +000017#include "CXTranslationUnit.h"
Ted Kremenek4b4f3692010-11-16 01:56:27 +000018#include "CXString.h"
Ted Kremeneka5940822010-08-26 01:42:22 +000019#include "CXType.h"
Ted Kremenek97a45372010-01-25 22:34:44 +000020#include "CXSourceLocation.h"
Douglas Gregor4f9c3762010-01-28 00:27:43 +000021#include "CIndexDiagnostic.h"
Ted Kremenek0ec2cca2010-01-05 19:32:54 +000022
Ted Kremenekc0f3f722010-01-22 22:44:15 +000023#include "clang/Basic/Version.h"
Douglas Gregorba965fb2010-01-28 00:56:43 +000024
Steve Naroffa1c72842009-08-28 15:28:48 +000025#include "clang/AST/DeclVisitor.h"
Steve Naroff66af1ae2009-09-22 19:25:29 +000026#include "clang/AST/StmtVisitor.h"
Douglas Gregor93f89952010-01-21 16:28:34 +000027#include "clang/AST/TypeLocVisitor.h"
Benjamin Kramer064414532010-04-12 19:45:50 +000028#include "clang/Basic/Diagnostic.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
Douglas Gregorba965fb2010-01-28 00:56:43 +000031#include "clang/Frontend/FrontendDiagnostic.h"
Ted Kremenek2a43fd52010-01-06 23:43:31 +000032#include "clang/Lex/Lexer.h"
Benjamin Kramer064414532010-04-12 19:45:50 +000033#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregor562c1f92010-01-22 19:49:59 +000034#include "clang/Lex/Preprocessor.h"
Douglas Gregorf3af3112010-09-09 21:42:20 +000035#include "llvm/ADT/STLExtras.h"
Ted Kremenekd40a4392010-11-02 23:10:24 +000036#include "llvm/ADT/Optional.h"
Douglas Gregorf2f08062011-03-08 17:10:18 +000037#include "llvm/ADT/StringSwitch.h"
Ted Kremenekd40a4392010-11-02 23:10:24 +000038#include "clang/Analysis/Support/SaveAndRestore.h"
Daniel Dunbarc91f2ff2010-08-18 18:43:14 +000039#include "llvm/Support/CrashRecoveryContext.h"
Daniel Dunbara5af410d2010-10-08 19:30:33 +000040#include "llvm/Support/PrettyStackTrace.h"
Douglas Gregord3d923a2009-10-16 21:24:31 +000041#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor97c75712010-10-02 22:49:11 +000042#include "llvm/Support/raw_ostream.h"
Douglas Gregor8ef4c802010-08-09 21:00:09 +000043#include "llvm/Support/Timer.h"
Michael J. Spencer8aaf4992010-11-29 18:12:39 +000044#include "llvm/Support/Mutex.h"
45#include "llvm/Support/Program.h"
46#include "llvm/Support/Signals.h"
47#include "llvm/Support/Threading.h"
Ted Kremenekacd03f62010-11-15 23:11:54 +000048#include "llvm/Support/Compiler.h"
Ted Kremenek428c6372009-10-19 21:44:57 +000049
Steve Naroffa1c72842009-08-28 15:28:48 +000050using namespace clang;
Ted Kremenek87553c42010-01-15 20:35:54 +000051using namespace clang::cxcursor;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +000052using namespace clang::cxstring;
Steve Naroffa1c72842009-08-28 15:28:48 +000053
Ted Kremenek91554282010-11-16 08:15:36 +000054static CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) {
55 if (!TU)
56 return 0;
57 CXTranslationUnit D = new CXTranslationUnitImpl();
58 D->TUData = TU;
59 D->StringPool = createCXStringPool();
60 return D;
61}
62
Douglas Gregor562c1f92010-01-22 19:49:59 +000063/// \brief The result of comparing two source ranges.
64enum RangeComparisonResult {
65 /// \brief Either the ranges overlap or one of the ranges is invalid.
66 RangeOverlap,
Ted Kremenekf441baf2010-02-17 00:41:40 +000067
Douglas Gregor562c1f92010-01-22 19:49:59 +000068 /// \brief The first range ends before the second range starts.
69 RangeBefore,
Ted Kremenekf441baf2010-02-17 00:41:40 +000070
Douglas Gregor562c1f92010-01-22 19:49:59 +000071 /// \brief The first range starts after the second range ends.
72 RangeAfter
73};
74
Ted Kremenekf441baf2010-02-17 00:41:40 +000075/// \brief Compare two source ranges to determine their relative position in
Douglas Gregor562c1f92010-01-22 19:49:59 +000076/// the translation unit.
Ted Kremenekf441baf2010-02-17 00:41:40 +000077static RangeComparisonResult RangeCompare(SourceManager &SM,
78 SourceRange R1,
Douglas Gregor562c1f92010-01-22 19:49:59 +000079 SourceRange R2) {
80 assert(R1.isValid() && "First range is invalid?");
81 assert(R2.isValid() && "Second range is invalid?");
Douglas Gregorcd8bdd02010-07-22 20:22:31 +000082 if (R1.getEnd() != R2.getBegin() &&
Daniel Dunbar02968e52010-02-14 10:02:57 +000083 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
Douglas Gregor562c1f92010-01-22 19:49:59 +000084 return RangeBefore;
Douglas Gregorcd8bdd02010-07-22 20:22:31 +000085 if (R2.getEnd() != R1.getBegin() &&
Daniel Dunbar02968e52010-02-14 10:02:57 +000086 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
Douglas Gregor562c1f92010-01-22 19:49:59 +000087 return RangeAfter;
88 return RangeOverlap;
89}
90
Ted Kremenek680fe512010-05-05 00:55:23 +000091/// \brief Determine if a source location falls within, before, or after a
92/// a given source range.
93static RangeComparisonResult LocationCompare(SourceManager &SM,
94 SourceLocation L, SourceRange R) {
95 assert(R.isValid() && "First range is invalid?");
96 assert(L.isValid() && "Second range is invalid?");
Douglas Gregorcd8bdd02010-07-22 20:22:31 +000097 if (L == R.getBegin() || L == R.getEnd())
Ted Kremenek680fe512010-05-05 00:55:23 +000098 return RangeOverlap;
Ted Kremenek680fe512010-05-05 00:55:23 +000099 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
100 return RangeBefore;
101 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
102 return RangeAfter;
103 return RangeOverlap;
104}
105
Daniel Dunbar474b2072010-02-14 01:47:29 +0000106/// \brief Translate a Clang source range into a CIndex source range.
107///
108/// Clang internally represents ranges where the end location points to the
109/// start of the token at the end. However, for external clients it is more
110/// useful to have a CXSourceRange be a proper half-open interval. This routine
111/// does the appropriate translation.
Ted Kremenekf441baf2010-02-17 00:41:40 +0000112CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
Daniel Dunbar474b2072010-02-14 01:47:29 +0000113 const LangOptions &LangOpts,
Chris Lattnered8b6b72010-06-18 22:45:06 +0000114 const CharSourceRange &R) {
Daniel Dunbar474b2072010-02-14 01:47:29 +0000115 // We want the last character in this location, so we will adjust the
Douglas Gregoraae92242010-03-19 21:51:54 +0000116 // location accordingly.
Daniel Dunbar474b2072010-02-14 01:47:29 +0000117 SourceLocation EndLoc = R.getEnd();
Douglas Gregor229bebd2010-11-09 06:24:54 +0000118 if (EndLoc.isValid() && EndLoc.isMacroID())
119 EndLoc = SM.getSpellingLoc(EndLoc);
Chris Lattnered8b6b72010-06-18 22:45:06 +0000120 if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
Douglas Gregoraae92242010-03-19 21:51:54 +0000121 unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
Daniel Dunbar474b2072010-02-14 01:47:29 +0000122 EndLoc = EndLoc.getFileLocWithOffset(Length);
123 }
124
125 CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
126 R.getBegin().getRawEncoding(),
127 EndLoc.getRawEncoding() };
128 return Result;
129}
Douglas Gregor4f46e782010-01-19 21:36:55 +0000130
Ted Kremenek991eb3f2010-01-06 03:42:32 +0000131//===----------------------------------------------------------------------===//
Douglas Gregor562c1f92010-01-22 19:49:59 +0000132// Cursor visitor.
Ted Kremenek991eb3f2010-01-06 03:42:32 +0000133//===----------------------------------------------------------------------===//
134
Steve Naroff1054e602009-08-31 00:59:03 +0000135namespace {
Ted Kremenek92209a42010-11-11 08:05:18 +0000136
137class VisitorJob {
138public:
Ted Kremeneke12bcf52010-11-12 21:34:12 +0000139 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
Ted Kremenek573411b2010-11-13 00:58:18 +0000140 TypeLocVisitKind, OverloadExprPartsKind,
Ted Kremenek8eaa1652010-11-17 00:50:47 +0000141 DeclRefExprPartsKind, LabelRefVisitKind,
Ted Kremenek83900272010-11-18 00:02:32 +0000142 ExplicitTemplateArgsVisitKind,
143 NestedNameSpecifierVisitKind,
Douglas Gregora6ce6082011-02-25 18:19:59 +0000144 NestedNameSpecifierLocVisitKind,
Ted Kremenek5d304a32010-11-18 00:42:18 +0000145 DeclarationNameInfoVisitKind,
Douglas Gregor557f05c2011-01-19 20:34:17 +0000146 MemberRefVisitKind, SizeOfPackExprPartsKind };
Ted Kremenek92209a42010-11-11 08:05:18 +0000147protected:
Ted Kremenek83900272010-11-18 00:02:32 +0000148 void *data[3];
Ted Kremenek92209a42010-11-11 08:05:18 +0000149 CXCursor parent;
150 Kind K;
Ted Kremenek83900272010-11-18 00:02:32 +0000151 VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
152 : parent(C), K(k) {
153 data[0] = d1;
154 data[1] = d2;
155 data[2] = d3;
156 }
Ted Kremenek92209a42010-11-11 08:05:18 +0000157public:
158 Kind getKind() const { return K; }
159 const CXCursor &getParent() const { return parent; }
160 static bool classof(VisitorJob *VJ) { return true; }
161};
162
163typedef llvm::SmallVector<VisitorJob, 10> VisitorWorkList;
164
Douglas Gregor71f3d942010-01-20 20:59:29 +0000165// Cursor visitor.
Douglas Gregor93f89952010-01-21 16:28:34 +0000166class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
Ted Kremenek5d304a32010-11-18 00:42:18 +0000167 public TypeLocVisitor<CursorVisitor, bool>
Douglas Gregor93f89952010-01-21 16:28:34 +0000168{
Douglas Gregor562c1f92010-01-22 19:49:59 +0000169 /// \brief The translation unit we are traversing.
Ted Kremenek91554282010-11-16 08:15:36 +0000170 CXTranslationUnit TU;
171 ASTUnit *AU;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000172
Douglas Gregor562c1f92010-01-22 19:49:59 +0000173 /// \brief The parent cursor whose children we are traversing.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000174 CXCursor Parent;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000175
Douglas Gregor562c1f92010-01-22 19:49:59 +0000176 /// \brief The declaration that serves at the parent of any statement or
177 /// expression nodes.
Douglas Gregord1824312010-01-21 17:29:07 +0000178 Decl *StmtParent;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000179
Douglas Gregor562c1f92010-01-22 19:49:59 +0000180 /// \brief The visitor function.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000181 CXCursorVisitor Visitor;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000182
Douglas Gregor562c1f92010-01-22 19:49:59 +0000183 /// \brief The opaque client data, to be passed along to the visitor.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000184 CXClientData ClientData;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000185
Douglas Gregor16bef852009-10-16 20:01:17 +0000186 // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
187 // to the visitor. Declarations with a PCH level greater than this value will
188 // be suppressed.
189 unsigned MaxPCHLevel;
Douglas Gregor562c1f92010-01-22 19:49:59 +0000190
Douglas Gregorc2b97992011-03-16 23:23:30 +0000191 /// \brief Whether we should visit the preprocessing record entries last,
192 /// after visiting other declarations.
193 bool VisitPreprocessorLast;
194
Douglas Gregor562c1f92010-01-22 19:49:59 +0000195 /// \brief When valid, a source range to which the cursor should restrict
196 /// its search.
197 SourceRange RegionOfInterest;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000198
Ted Kremenekd40a4392010-11-02 23:10:24 +0000199 // FIXME: Eventually remove. This part of a hack to support proper
200 // iteration over all Decls contained lexically within an ObjC container.
201 DeclContext::decl_iterator *DI_current;
202 DeclContext::decl_iterator DE_current;
203
Ted Kremeneka4c27ec2010-11-15 23:31:32 +0000204 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
205 llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
206 llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
207
Douglas Gregor71f3d942010-01-20 20:59:29 +0000208 using DeclVisitor<CursorVisitor, bool>::Visit;
Douglas Gregor93f89952010-01-21 16:28:34 +0000209 using TypeLocVisitor<CursorVisitor, bool>::Visit;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000210
211 /// \brief Determine whether this particular source range comes before, comes
212 /// after, or overlaps the region of interest.
Douglas Gregor562c1f92010-01-22 19:49:59 +0000213 ///
Daniel Dunbar02968e52010-02-14 10:02:57 +0000214 /// \param R a half-open source range retrieved from the abstract syntax tree.
Ted Kremenekf441baf2010-02-17 00:41:40 +0000215 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
216
Ted Kremenek12e0f292010-05-13 00:25:00 +0000217 class SetParentRAII {
218 CXCursor &Parent;
219 Decl *&StmtParent;
220 CXCursor OldParent;
221
222 public:
223 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
224 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
225 {
226 Parent = NewParent;
227 if (clang_isDeclaration(Parent.kind))
228 StmtParent = getCursorDecl(Parent);
229 }
230
231 ~SetParentRAII() {
232 Parent = OldParent;
233 if (clang_isDeclaration(Parent.kind))
234 StmtParent = getCursorDecl(Parent);
235 }
236 };
237
Steve Naroff1054e602009-08-31 00:59:03 +0000238public:
Ted Kremenek91554282010-11-16 08:15:36 +0000239 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
240 CXClientData ClientData,
Ted Kremenekf441baf2010-02-17 00:41:40 +0000241 unsigned MaxPCHLevel,
Douglas Gregorc2b97992011-03-16 23:23:30 +0000242 bool VisitPreprocessorLast,
Douglas Gregor562c1f92010-01-22 19:49:59 +0000243 SourceRange RegionOfInterest = SourceRange())
Ted Kremenek91554282010-11-16 08:15:36 +0000244 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
245 Visitor(Visitor), ClientData(ClientData),
Douglas Gregorc2b97992011-03-16 23:23:30 +0000246 MaxPCHLevel(MaxPCHLevel), VisitPreprocessorLast(VisitPreprocessorLast),
247 RegionOfInterest(RegionOfInterest), DI_current(0)
Douglas Gregor71f3d942010-01-20 20:59:29 +0000248 {
249 Parent.kind = CXCursor_NoDeclFound;
250 Parent.data[0] = 0;
251 Parent.data[1] = 0;
252 Parent.data[2] = 0;
Douglas Gregord1824312010-01-21 17:29:07 +0000253 StmtParent = 0;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000254 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000255
Ted Kremeneka4c27ec2010-11-15 23:31:32 +0000256 ~CursorVisitor() {
257 // Free the pre-allocated worklists for data-recursion.
258 for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
259 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
260 delete *I;
261 }
262 }
263
Ted Kremenek91554282010-11-16 08:15:36 +0000264 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
265 CXTranslationUnit getTU() const { return TU; }
Ted Kremenekc7a5bae2010-11-11 08:05:23 +0000266
Douglas Gregor562c1f92010-01-22 19:49:59 +0000267 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000268
269 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
270 getPreprocessedEntities();
271
Douglas Gregor71f3d942010-01-20 20:59:29 +0000272 bool VisitChildren(CXCursor Parent);
Ted Kremenekf441baf2010-02-17 00:41:40 +0000273
Douglas Gregor93f89952010-01-21 16:28:34 +0000274 // Declaration visitors
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);
2776 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID);
2777 if (!sloc.isFile()) {
2778 createNullLocation(file, line, column, offset);
2779 return;
2780 }
2781
Douglas Gregor4f46e782010-01-19 21:36:55 +00002782 if (file)
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002783 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002784 if (line)
2785 *line = SM.getInstantiationLineNumber(InstLoc);
2786 if (column)
2787 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregor47751d62010-01-26 03:07:15 +00002788 if (offset)
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002789 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregor47751d62010-01-26 03:07:15 +00002790}
2791
Douglas Gregor229bebd2010-11-09 06:24:54 +00002792void clang_getSpellingLocation(CXSourceLocation location,
2793 CXFile *file,
2794 unsigned *line,
2795 unsigned *column,
2796 unsigned *offset) {
2797 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2798
2799 if (!location.ptr_data[0] || Loc.isInvalid()) {
2800 if (file)
2801 *file = 0;
2802 if (line)
2803 *line = 0;
2804 if (column)
2805 *column = 0;
2806 if (offset)
2807 *offset = 0;
2808 return;
2809 }
2810
2811 const SourceManager &SM =
2812 *static_cast<const SourceManager*>(location.ptr_data[0]);
2813 SourceLocation SpellLoc = Loc;
2814 if (SpellLoc.isMacroID()) {
2815 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2816 if (SimpleSpellingLoc.isFileID() &&
2817 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2818 SpellLoc = SimpleSpellingLoc;
2819 else
2820 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2821 }
2822
2823 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2824 FileID FID = LocInfo.first;
2825 unsigned FileOffset = LocInfo.second;
2826
2827 if (file)
2828 *file = (void *)SM.getFileEntryForID(FID);
2829 if (line)
2830 *line = SM.getLineNumber(FID, FileOffset);
2831 if (column)
2832 *column = SM.getColumnNumber(FID, FileOffset);
2833 if (offset)
2834 *offset = FileOffset;
2835}
2836
Douglas Gregor4f46e782010-01-19 21:36:55 +00002837CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002838 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002839 range.begin_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002840 return Result;
2841}
2842
2843CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002844 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002845 range.end_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002846 return Result;
2847}
2848
Douglas Gregor816fd362010-01-22 21:44:22 +00002849} // end: extern "C"
2850
Douglas Gregor4f46e782010-01-19 21:36:55 +00002851//===----------------------------------------------------------------------===//
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002852// CXFile Operations.
2853//===----------------------------------------------------------------------===//
2854
2855extern "C" {
Ted Kremenekc560b682010-02-17 00:41:20 +00002856CXString clang_getFileName(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002857 if (!SFile)
Ted Kremenek91554282010-11-16 08:15:36 +00002858 return createCXString((const char*)NULL);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002859
Steve Naroff6231f182009-10-27 14:35:18 +00002860 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenekc560b682010-02-17 00:41:20 +00002861 return createCXString(FEnt->getName());
Steve Naroff6231f182009-10-27 14:35:18 +00002862}
2863
2864time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002865 if (!SFile)
2866 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002867
Steve Naroff6231f182009-10-27 14:35:18 +00002868 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2869 return FEnt->getModificationTime();
Steve Naroff26760892009-09-25 21:45:39 +00002870}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002871
Douglas Gregor816fd362010-01-22 21:44:22 +00002872CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2873 if (!tu)
2874 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002875
Ted Kremenek91554282010-11-16 08:15:36 +00002876 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002877
Douglas Gregor816fd362010-01-22 21:44:22 +00002878 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner5159f612010-11-23 08:35:12 +00002879 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregor816fd362010-01-22 21:44:22 +00002880}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002881
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002882} // end: extern "C"
Steve Naroff26760892009-09-25 21:45:39 +00002883
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002884//===----------------------------------------------------------------------===//
2885// CXCursor Operations.
2886//===----------------------------------------------------------------------===//
2887
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002888static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregore6712982010-10-01 21:11:22 +00002889 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2890 return getDeclFromExpr(CE->getSubExpr());
2891
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002892 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2893 return RefExpr->getDecl();
Douglas Gregor263803a2010-10-22 22:24:08 +00002894 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2895 return RefExpr->getDecl();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002896 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2897 return ME->getMemberDecl();
2898 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2899 return RE->getDecl();
Douglas Gregore6712982010-10-01 21:11:22 +00002900 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCallb7bd14f2010-12-02 01:19:52 +00002901 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregore6712982010-10-01 21:11:22 +00002902
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002903 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2904 return getDeclFromExpr(CE->getCallee());
Douglas Gregor16443fd2010-11-05 21:11:19 +00002905 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2906 if (!CE->isElidable())
2907 return CE->getConstructor();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002908 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2909 return OME->getMethodDecl();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002910
Douglas Gregore6712982010-10-01 21:11:22 +00002911 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2912 return PE->getProtocol();
Douglas Gregorcdbc5392011-01-15 01:15:58 +00002913 if (SubstNonTypeTemplateParmPackExpr *NTTP
2914 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2915 return NTTP->getParameterPack();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002916 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2917 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2918 isa<ParmVarDecl>(SizeOfPack->getPack()))
2919 return SizeOfPack->getPack();
Douglas Gregore6712982010-10-01 21:11:22 +00002920
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002921 return 0;
2922}
2923
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002924static SourceLocation getLocationFromExpr(Expr *E) {
2925 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2926 return /*FIXME:*/Msg->getLeftLoc();
2927 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2928 return DRE->getLocation();
Douglas Gregor263803a2010-10-22 22:24:08 +00002929 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2930 return RefExpr->getLocation();
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002931 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2932 return Member->getMemberLoc();
2933 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2934 return Ivar->getLocation();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002935 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2936 return SizeOfPack->getPackLoc();
2937
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002938 return E->getLocStart();
2939}
2940
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002941extern "C" {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002942
2943unsigned clang_visitChildren(CXCursor parent,
Douglas Gregor71f3d942010-01-20 20:59:29 +00002944 CXCursorVisitor visitor,
2945 CXClientData client_data) {
Ted Kremenek91554282010-11-16 08:15:36 +00002946 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregorc2b97992011-03-16 23:23:30 +00002947 getCursorASTUnit(parent)->getMaxPCHLevel(),
2948 false);
Douglas Gregor71f3d942010-01-20 20:59:29 +00002949 return CursorVis.VisitChildren(parent);
2950}
2951
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002952#ifndef __has_feature
2953#define __has_feature(x) 0
2954#endif
2955#if __has_feature(blocks)
2956typedef enum CXChildVisitResult
2957 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2958
2959static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2960 CXClientData client_data) {
2961 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2962 return block(cursor, parent);
2963}
2964#else
2965// If we are compiled with a compiler that doesn't have native blocks support,
2966// define and call the block manually, so the
2967typedef struct _CXChildVisitResult
2968{
2969 void *isa;
2970 int flags;
2971 int reserved;
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002972 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2973 CXCursor);
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002974} *CXCursorVisitorBlock;
2975
2976static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2977 CXClientData client_data) {
2978 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2979 return block->invoke(block, cursor, parent);
2980}
2981#endif
2982
2983
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002984unsigned clang_visitChildrenWithBlock(CXCursor parent,
2985 CXCursorVisitorBlock block) {
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002986 return clang_visitChildren(parent, visitWithBlock, block);
2987}
2988
Douglas Gregordd969c82010-01-20 21:45:58 +00002989static CXString getDeclSpelling(Decl *D) {
2990 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002991 if (!ND) {
2992 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2993 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2994 return createCXString(Property->getIdentifier()->getName());
2995
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002996 return createCXString("");
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002997 }
2998
Douglas Gregordd969c82010-01-20 21:45:58 +00002999 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003000 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf441baf2010-02-17 00:41:40 +00003001
Douglas Gregordd969c82010-01-20 21:45:58 +00003002 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
3003 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3004 // and returns different names. NamedDecl returns the class name and
3005 // ObjCCategoryImplDecl returns the category name.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003006 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf441baf2010-02-17 00:41:40 +00003007
Douglas Gregor01a430132010-09-01 03:07:18 +00003008 if (isa<UsingDirectiveDecl>(D))
3009 return createCXString("");
3010
Ted Kremenek08de5c12010-05-19 21:51:10 +00003011 llvm::SmallString<1024> S;
3012 llvm::raw_svector_ostream os(S);
3013 ND->printName(os);
3014
3015 return createCXString(os.str());
Douglas Gregordd969c82010-01-20 21:45:58 +00003016}
Ted Kremenekf441baf2010-02-17 00:41:40 +00003017
Daniel Dunbar079203f2009-12-01 03:14:51 +00003018CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregord2fc7272010-01-20 00:23:15 +00003019 if (clang_isTranslationUnit(C.kind))
Ted Kremenek91554282010-11-16 08:15:36 +00003020 return clang_getTranslationUnitSpelling(
3021 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregord2fc7272010-01-20 00:23:15 +00003022
Steve Naroff80a766b2009-09-02 18:26:48 +00003023 if (clang_isReference(C.kind)) {
3024 switch (C.kind) {
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003025 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor6c8959b2010-01-16 14:00:32 +00003026 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003027 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003028 }
3029 case CXCursor_ObjCClassRef: {
Douglas Gregor46d66142010-01-16 17:14:40 +00003030 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003031 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003032 }
3033 case CXCursor_ObjCProtocolRef: {
Douglas Gregoref6eb842010-01-16 15:44:18 +00003034 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003035 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003036 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003037 }
Ted Kremenekae9e2212010-08-27 21:34:58 +00003038 case CXCursor_CXXBaseSpecifier: {
3039 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3040 return createCXString(B->getType().getAsString());
3041 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003042 case CXCursor_TypeRef: {
3043 TypeDecl *Type = getCursorTypeRef(C).first;
3044 assert(Type && "Missing type decl");
3045
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003046 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3047 getAsString());
Douglas Gregor93f89952010-01-21 16:28:34 +00003048 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00003049 case CXCursor_TemplateRef: {
3050 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregora89314e2010-08-31 23:48:11 +00003051 assert(Template && "Missing template decl");
Douglas Gregora23e8f72010-08-31 20:37:03 +00003052
3053 return createCXString(Template->getNameAsString());
3054 }
Douglas Gregora89314e2010-08-31 23:48:11 +00003055
3056 case CXCursor_NamespaceRef: {
3057 NamedDecl *NS = getCursorNamespaceRef(C).first;
3058 assert(NS && "Missing namespace decl");
3059
3060 return createCXString(NS->getNameAsString());
3061 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003062
Douglas Gregorf3af3112010-09-09 21:42:20 +00003063 case CXCursor_MemberRef: {
3064 FieldDecl *Field = getCursorMemberRef(C).first;
3065 assert(Field && "Missing member decl");
3066
3067 return createCXString(Field->getNameAsString());
3068 }
3069
Douglas Gregora93ab662010-09-10 00:22:18 +00003070 case CXCursor_LabelRef: {
3071 LabelStmt *Label = getCursorLabelRef(C).first;
3072 assert(Label && "Missing label");
3073
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003074 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00003075 }
3076
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003077 case CXCursor_OverloadedDeclRef: {
3078 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3079 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3080 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3081 return createCXString(ND->getNameAsString());
3082 return createCXString("");
3083 }
3084 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3085 return createCXString(E->getName().getAsString());
3086 OverloadedTemplateStorage *Ovl
3087 = Storage.get<OverloadedTemplateStorage*>();
3088 if (Ovl->size() == 0)
3089 return createCXString("");
3090 return createCXString((*Ovl->begin())->getNameAsString());
3091 }
3092
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003093 default:
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003094 return createCXString("<not implemented>");
Steve Naroff80a766b2009-09-02 18:26:48 +00003095 }
3096 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003097
3098 if (clang_isExpression(C.kind)) {
3099 Decl *D = getDeclFromExpr(getCursorExpr(C));
3100 if (D)
Douglas Gregordd969c82010-01-20 21:45:58 +00003101 return getDeclSpelling(D);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003102 return createCXString("");
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003103 }
3104
Douglas Gregora93ab662010-09-10 00:22:18 +00003105 if (clang_isStatement(C.kind)) {
3106 Stmt *S = getCursorStmt(C);
3107 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003108 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00003109
3110 return createCXString("");
3111 }
3112
Douglas Gregor065f8d12010-03-18 17:52:52 +00003113 if (C.kind == CXCursor_MacroInstantiation)
3114 return createCXString(getCursorMacroInstantiation(C)->getName()
3115 ->getNameStart());
3116
Douglas Gregor06d6d322010-03-18 18:04:21 +00003117 if (C.kind == CXCursor_MacroDefinition)
3118 return createCXString(getCursorMacroDefinition(C)->getName()
3119 ->getNameStart());
3120
Douglas Gregor796d76a2010-10-20 22:00:55 +00003121 if (C.kind == CXCursor_InclusionDirective)
3122 return createCXString(getCursorInclusionDirective(C)->getFileName());
3123
Douglas Gregor5bce76c2010-01-25 16:56:17 +00003124 if (clang_isDeclaration(C.kind))
3125 return getDeclSpelling(getCursorDecl(C));
Ted Kremenek29004672010-02-17 00:41:32 +00003126
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003127 return createCXString("");
Steve Naroff80a766b2009-09-02 18:26:48 +00003128}
3129
Douglas Gregor97c75712010-10-02 22:49:11 +00003130CXString clang_getCursorDisplayName(CXCursor C) {
3131 if (!clang_isDeclaration(C.kind))
3132 return clang_getCursorSpelling(C);
3133
3134 Decl *D = getCursorDecl(C);
3135 if (!D)
3136 return createCXString("");
3137
3138 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3139 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3140 D = FunTmpl->getTemplatedDecl();
3141
3142 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3143 llvm::SmallString<64> Str;
3144 llvm::raw_svector_ostream OS(Str);
3145 OS << Function->getNameAsString();
3146 if (Function->getPrimaryTemplate())
3147 OS << "<>";
3148 OS << "(";
3149 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3150 if (I)
3151 OS << ", ";
3152 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3153 }
3154
3155 if (Function->isVariadic()) {
3156 if (Function->getNumParams())
3157 OS << ", ";
3158 OS << "...";
3159 }
3160 OS << ")";
3161 return createCXString(OS.str());
3162 }
3163
3164 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3165 llvm::SmallString<64> Str;
3166 llvm::raw_svector_ostream OS(Str);
3167 OS << ClassTemplate->getNameAsString();
3168 OS << "<";
3169 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3170 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3171 if (I)
3172 OS << ", ";
3173
3174 NamedDecl *Param = Params->getParam(I);
3175 if (Param->getIdentifier()) {
3176 OS << Param->getIdentifier()->getName();
3177 continue;
3178 }
3179
3180 // There is no parameter name, which makes this tricky. Try to come up
3181 // with something useful that isn't too long.
3182 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3183 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3184 else if (NonTypeTemplateParmDecl *NTTP
3185 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3186 OS << NTTP->getType().getAsString(Policy);
3187 else
3188 OS << "template<...> class";
3189 }
3190
3191 OS << ">";
3192 return createCXString(OS.str());
3193 }
3194
3195 if (ClassTemplateSpecializationDecl *ClassSpec
3196 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3197 // If the type was explicitly written, use that.
3198 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3199 return createCXString(TSInfo->getType().getAsString(Policy));
3200
3201 llvm::SmallString<64> Str;
3202 llvm::raw_svector_ostream OS(Str);
3203 OS << ClassSpec->getNameAsString();
3204 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor1ccc8412010-11-07 23:05:16 +00003205 ClassSpec->getTemplateArgs().data(),
3206 ClassSpec->getTemplateArgs().size(),
Douglas Gregor97c75712010-10-02 22:49:11 +00003207 Policy);
3208 return createCXString(OS.str());
3209 }
3210
3211 return clang_getCursorSpelling(C);
3212}
3213
Ted Kremenek29004672010-02-17 00:41:32 +00003214CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff1054e602009-08-31 00:59:03 +00003215 switch (Kind) {
Ted Kremenek29004672010-02-17 00:41:32 +00003216 case CXCursor_FunctionDecl:
3217 return createCXString("FunctionDecl");
3218 case CXCursor_TypedefDecl:
3219 return createCXString("TypedefDecl");
3220 case CXCursor_EnumDecl:
3221 return createCXString("EnumDecl");
3222 case CXCursor_EnumConstantDecl:
3223 return createCXString("EnumConstantDecl");
3224 case CXCursor_StructDecl:
3225 return createCXString("StructDecl");
3226 case CXCursor_UnionDecl:
3227 return createCXString("UnionDecl");
3228 case CXCursor_ClassDecl:
3229 return createCXString("ClassDecl");
3230 case CXCursor_FieldDecl:
3231 return createCXString("FieldDecl");
3232 case CXCursor_VarDecl:
3233 return createCXString("VarDecl");
3234 case CXCursor_ParmDecl:
3235 return createCXString("ParmDecl");
3236 case CXCursor_ObjCInterfaceDecl:
3237 return createCXString("ObjCInterfaceDecl");
3238 case CXCursor_ObjCCategoryDecl:
3239 return createCXString("ObjCCategoryDecl");
3240 case CXCursor_ObjCProtocolDecl:
3241 return createCXString("ObjCProtocolDecl");
3242 case CXCursor_ObjCPropertyDecl:
3243 return createCXString("ObjCPropertyDecl");
3244 case CXCursor_ObjCIvarDecl:
3245 return createCXString("ObjCIvarDecl");
3246 case CXCursor_ObjCInstanceMethodDecl:
3247 return createCXString("ObjCInstanceMethodDecl");
3248 case CXCursor_ObjCClassMethodDecl:
3249 return createCXString("ObjCClassMethodDecl");
3250 case CXCursor_ObjCImplementationDecl:
3251 return createCXString("ObjCImplementationDecl");
3252 case CXCursor_ObjCCategoryImplDecl:
3253 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek225b8e32010-04-13 23:39:06 +00003254 case CXCursor_CXXMethod:
3255 return createCXString("CXXMethod");
Ted Kremenek29004672010-02-17 00:41:32 +00003256 case CXCursor_UnexposedDecl:
3257 return createCXString("UnexposedDecl");
3258 case CXCursor_ObjCSuperClassRef:
3259 return createCXString("ObjCSuperClassRef");
3260 case CXCursor_ObjCProtocolRef:
3261 return createCXString("ObjCProtocolRef");
3262 case CXCursor_ObjCClassRef:
3263 return createCXString("ObjCClassRef");
3264 case CXCursor_TypeRef:
3265 return createCXString("TypeRef");
Douglas Gregora23e8f72010-08-31 20:37:03 +00003266 case CXCursor_TemplateRef:
3267 return createCXString("TemplateRef");
Douglas Gregora89314e2010-08-31 23:48:11 +00003268 case CXCursor_NamespaceRef:
3269 return createCXString("NamespaceRef");
Douglas Gregorf3af3112010-09-09 21:42:20 +00003270 case CXCursor_MemberRef:
3271 return createCXString("MemberRef");
Douglas Gregora93ab662010-09-10 00:22:18 +00003272 case CXCursor_LabelRef:
3273 return createCXString("LabelRef");
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003274 case CXCursor_OverloadedDeclRef:
3275 return createCXString("OverloadedDeclRef");
Ted Kremenek29004672010-02-17 00:41:32 +00003276 case CXCursor_UnexposedExpr:
3277 return createCXString("UnexposedExpr");
Ted Kremenek33b9a422010-04-11 21:47:37 +00003278 case CXCursor_BlockExpr:
3279 return createCXString("BlockExpr");
Ted Kremenek29004672010-02-17 00:41:32 +00003280 case CXCursor_DeclRefExpr:
3281 return createCXString("DeclRefExpr");
3282 case CXCursor_MemberRefExpr:
3283 return createCXString("MemberRefExpr");
3284 case CXCursor_CallExpr:
3285 return createCXString("CallExpr");
3286 case CXCursor_ObjCMessageExpr:
3287 return createCXString("ObjCMessageExpr");
3288 case CXCursor_UnexposedStmt:
3289 return createCXString("UnexposedStmt");
Douglas Gregora93ab662010-09-10 00:22:18 +00003290 case CXCursor_LabelStmt:
3291 return createCXString("LabelStmt");
Ted Kremenek29004672010-02-17 00:41:32 +00003292 case CXCursor_InvalidFile:
3293 return createCXString("InvalidFile");
Ted Kremenek00da3b92010-03-19 20:39:05 +00003294 case CXCursor_InvalidCode:
3295 return createCXString("InvalidCode");
Ted Kremenek29004672010-02-17 00:41:32 +00003296 case CXCursor_NoDeclFound:
3297 return createCXString("NoDeclFound");
3298 case CXCursor_NotImplemented:
3299 return createCXString("NotImplemented");
3300 case CXCursor_TranslationUnit:
3301 return createCXString("TranslationUnit");
Ted Kremenekbff31432010-02-18 03:09:07 +00003302 case CXCursor_UnexposedAttr:
3303 return createCXString("UnexposedAttr");
3304 case CXCursor_IBActionAttr:
3305 return createCXString("attribute(ibaction)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003306 case CXCursor_IBOutletAttr:
3307 return createCXString("attribute(iboutlet)");
Ted Kremenek26bde772010-05-19 17:38:06 +00003308 case CXCursor_IBOutletCollectionAttr:
3309 return createCXString("attribute(iboutletcollection)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003310 case CXCursor_PreprocessingDirective:
3311 return createCXString("preprocessing directive");
Douglas Gregor06d6d322010-03-18 18:04:21 +00003312 case CXCursor_MacroDefinition:
3313 return createCXString("macro definition");
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003314 case CXCursor_MacroInstantiation:
3315 return createCXString("macro instantiation");
Douglas Gregor796d76a2010-10-20 22:00:55 +00003316 case CXCursor_InclusionDirective:
3317 return createCXString("inclusion directive");
Ted Kremenekbd67fb22010-05-06 23:38:21 +00003318 case CXCursor_Namespace:
3319 return createCXString("Namespace");
Ted Kremenekb80cba52010-05-07 01:04:29 +00003320 case CXCursor_LinkageSpec:
3321 return createCXString("LinkageSpec");
Ted Kremenekae9e2212010-08-27 21:34:58 +00003322 case CXCursor_CXXBaseSpecifier:
3323 return createCXString("C++ base class specifier");
Douglas Gregor12bca222010-08-31 14:41:23 +00003324 case CXCursor_Constructor:
3325 return createCXString("CXXConstructor");
3326 case CXCursor_Destructor:
3327 return createCXString("CXXDestructor");
3328 case CXCursor_ConversionFunction:
3329 return createCXString("CXXConversion");
Douglas Gregor713602b2010-08-31 17:01:39 +00003330 case CXCursor_TemplateTypeParameter:
3331 return createCXString("TemplateTypeParameter");
3332 case CXCursor_NonTypeTemplateParameter:
3333 return createCXString("NonTypeTemplateParameter");
3334 case CXCursor_TemplateTemplateParameter:
3335 return createCXString("TemplateTemplateParameter");
3336 case CXCursor_FunctionTemplate:
3337 return createCXString("FunctionTemplate");
Douglas Gregor1fbaeb12010-08-31 19:02:00 +00003338 case CXCursor_ClassTemplate:
3339 return createCXString("ClassTemplate");
Douglas Gregorf96abb22010-08-31 19:31:58 +00003340 case CXCursor_ClassTemplatePartialSpecialization:
3341 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregora89314e2010-08-31 23:48:11 +00003342 case CXCursor_NamespaceAlias:
3343 return createCXString("NamespaceAlias");
Douglas Gregor01a430132010-09-01 03:07:18 +00003344 case CXCursor_UsingDirective:
3345 return createCXString("UsingDirective");
Douglas Gregora9aa29c2010-09-01 19:52:22 +00003346 case CXCursor_UsingDeclaration:
3347 return createCXString("UsingDeclaration");
Richard Smithdda56e42011-04-15 14:24:37 +00003348 case CXCursor_TypeAliasDecl:
3349 return createCXString("TypeAliasDecl");
Steve Naroff1054e602009-08-31 00:59:03 +00003350 }
Ted Kremenek29004672010-02-17 00:41:32 +00003351
Ted Kremenek4ba52632010-01-16 02:02:09 +00003352 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremenek91554282010-11-16 08:15:36 +00003353 return createCXString((const char*) 0);
Steve Naroffd5e8e862009-08-27 19:51:58 +00003354}
Steve Naroff1054e602009-08-31 00:59:03 +00003355
Ted Kremenek29004672010-02-17 00:41:32 +00003356enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3357 CXCursor parent,
Douglas Gregor562c1f92010-01-22 19:49:59 +00003358 CXClientData client_data) {
3359 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor16443fd2010-11-05 21:11:19 +00003360
3361 // If our current best cursor is the construction of a temporary object,
3362 // don't replace that cursor with a type reference, because we want
3363 // clang_getCursor() to point at the constructor.
3364 if (clang_isExpression(BestCursor->kind) &&
3365 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3366 cursor.kind == CXCursor_TypeRef)
3367 return CXChildVisit_Recurse;
3368
Douglas Gregor3046b4d2010-12-10 07:23:11 +00003369 // Don't override a preprocessing cursor with another preprocessing
3370 // cursor; we want the outermost preprocessing cursor.
3371 if (clang_isPreprocessing(cursor.kind) &&
3372 clang_isPreprocessing(BestCursor->kind))
3373 return CXChildVisit_Recurse;
3374
Douglas Gregor562c1f92010-01-22 19:49:59 +00003375 *BestCursor = cursor;
3376 return CXChildVisit_Recurse;
3377}
Ted Kremenek29004672010-02-17 00:41:32 +00003378
Douglas Gregor816fd362010-01-22 21:44:22 +00003379CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3380 if (!TU)
Ted Kremeneke34cbde2010-01-14 01:51:23 +00003381 return clang_getNullCursor();
Ted Kremenek29004672010-02-17 00:41:32 +00003382
Ted Kremenek91554282010-11-16 08:15:36 +00003383 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00003384 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3385
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003386 // Translate the given source location to make it point at the beginning of
3387 // the token under the cursor.
Ted Kremenek97a45372010-01-25 22:34:44 +00003388 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremenek1e589f22010-07-29 00:52:07 +00003389
3390 // Guard against an invalid SourceLocation, or we may assert in one
3391 // of the following calls.
3392 if (SLoc.isInvalid())
3393 return clang_getNullCursor();
3394
Douglas Gregor15417cf2010-11-03 00:35:38 +00003395 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003396 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3397 CXXUnit->getASTContext().getLangOptions());
3398
Douglas Gregor562c1f92010-01-22 19:49:59 +00003399 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3400 if (SLoc.isValid()) {
Douglas Gregor562c1f92010-01-22 19:49:59 +00003401 // FIXME: Would be great to have a "hint" cursor, then walk from that
3402 // hint cursor upward until we find a cursor whose source range encloses
3403 // the region of interest, rather than starting from the translation unit.
Ted Kremenek91554282010-11-16 08:15:36 +00003404 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3405 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregorc2b97992011-03-16 23:23:30 +00003406 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor562c1f92010-01-22 19:49:59 +00003407 CursorVis.VisitChildren(Parent);
Steve Naroff54f22fb2009-09-15 20:25:34 +00003408 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003409
3410 if (Logging) {
3411 CXFile SearchFile;
3412 unsigned SearchLine, SearchColumn;
3413 CXFile ResultFile;
3414 unsigned ResultLine, ResultColumn;
Douglas Gregor29ee4222010-11-17 17:14:07 +00003415 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3416 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor15417cf2010-11-03 00:35:38 +00003417 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3418
3419 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3420 0);
3421 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3422 &ResultColumn, 0);
3423 SearchFileName = clang_getFileName(SearchFile);
3424 ResultFileName = clang_getFileName(ResultFile);
3425 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003426 USR = clang_getCursorUSR(Result);
3427 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor15417cf2010-11-03 00:35:38 +00003428 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3429 clang_getCString(KindSpelling),
Douglas Gregor29ee4222010-11-17 17:14:07 +00003430 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3431 clang_getCString(USR), IsDef);
Douglas Gregor15417cf2010-11-03 00:35:38 +00003432 clang_disposeString(SearchFileName);
3433 clang_disposeString(ResultFileName);
3434 clang_disposeString(KindSpelling);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003435 clang_disposeString(USR);
Douglas Gregor4a5bd5f2010-12-10 01:45:00 +00003436
3437 CXCursor Definition = clang_getCursorDefinition(Result);
3438 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3439 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3440 CXString DefinitionKindSpelling
3441 = clang_getCursorKindSpelling(Definition.kind);
3442 CXFile DefinitionFile;
3443 unsigned DefinitionLine, DefinitionColumn;
3444 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3445 &DefinitionLine, &DefinitionColumn, 0);
3446 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3447 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3448 clang_getCString(DefinitionKindSpelling),
3449 clang_getCString(DefinitionFileName),
3450 DefinitionLine, DefinitionColumn);
3451 clang_disposeString(DefinitionFileName);
3452 clang_disposeString(DefinitionKindSpelling);
3453 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003454 }
3455
Ted Kremenek29004672010-02-17 00:41:32 +00003456 return Result;
Steve Naroffd5e8e862009-08-27 19:51:58 +00003457}
3458
Ted Kremeneke05d7802009-11-17 19:28:59 +00003459CXCursor clang_getNullCursor(void) {
Douglas Gregor58552bc2010-01-20 23:34:41 +00003460 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremeneke05d7802009-11-17 19:28:59 +00003461}
3462
3463unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00003464 return X == Y;
Ted Kremeneke05d7802009-11-17 19:28:59 +00003465}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00003466
Douglas Gregor06a3f302010-11-20 00:09:34 +00003467unsigned clang_hashCursor(CXCursor C) {
3468 unsigned Index = 0;
3469 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3470 Index = 1;
3471
3472 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3473 std::make_pair(C.kind, C.data[Index]));
3474}
3475
Daniel Dunbar079203f2009-12-01 03:14:51 +00003476unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff54f22fb2009-09-15 20:25:34 +00003477 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3478}
3479
Daniel Dunbar079203f2009-12-01 03:14:51 +00003480unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff1054e602009-08-31 00:59:03 +00003481 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3482}
Steve Naroff772c1a42009-08-31 14:26:51 +00003483
Daniel Dunbar079203f2009-12-01 03:14:51 +00003484unsigned clang_isReference(enum CXCursorKind K) {
Steve Naroff80a766b2009-09-02 18:26:48 +00003485 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3486}
3487
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003488unsigned clang_isExpression(enum CXCursorKind K) {
3489 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3490}
3491
3492unsigned clang_isStatement(enum CXCursorKind K) {
3493 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3494}
3495
Douglas Gregord2fc7272010-01-20 00:23:15 +00003496unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3497 return K == CXCursor_TranslationUnit;
3498}
3499
Douglas Gregor92a524f2010-03-18 00:42:48 +00003500unsigned clang_isPreprocessing(enum CXCursorKind K) {
3501 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3502}
3503
Ted Kremenekff9021b2010-03-08 21:17:29 +00003504unsigned clang_isUnexposed(enum CXCursorKind K) {
3505 switch (K) {
3506 case CXCursor_UnexposedDecl:
3507 case CXCursor_UnexposedExpr:
3508 case CXCursor_UnexposedStmt:
3509 case CXCursor_UnexposedAttr:
3510 return true;
3511 default:
3512 return false;
3513 }
3514}
3515
Daniel Dunbar079203f2009-12-01 03:14:51 +00003516CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroffef9618b2009-09-04 15:44:05 +00003517 return C.kind;
3518}
3519
Douglas Gregor66a58812010-01-18 22:46:11 +00003520CXSourceLocation clang_getCursorLocation(CXCursor C) {
3521 if (clang_isReference(C.kind)) {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003522 switch (C.kind) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00003523 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003524 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3525 = getCursorObjCSuperClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003526 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003527 }
3528
Ted Kremenekf441baf2010-02-17 00:41:40 +00003529 case CXCursor_ObjCProtocolRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003530 std::pair<ObjCProtocolDecl *, SourceLocation> P
3531 = getCursorObjCProtocolRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003532 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003533 }
3534
Ted Kremenekf441baf2010-02-17 00:41:40 +00003535 case CXCursor_ObjCClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003536 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3537 = getCursorObjCClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003538 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003539 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003540
Ted Kremenekf441baf2010-02-17 00:41:40 +00003541 case CXCursor_TypeRef: {
Douglas Gregor93f89952010-01-21 16:28:34 +00003542 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003543 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor93f89952010-01-21 16:28:34 +00003544 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00003545
3546 case CXCursor_TemplateRef: {
3547 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3548 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3549 }
3550
Douglas Gregora89314e2010-08-31 23:48:11 +00003551 case CXCursor_NamespaceRef: {
3552 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3553 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3554 }
3555
Douglas Gregorf3af3112010-09-09 21:42:20 +00003556 case CXCursor_MemberRef: {
3557 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3558 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3559 }
3560
Ted Kremenekae9e2212010-08-27 21:34:58 +00003561 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor3478c752010-10-02 19:51:13 +00003562 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3563 if (!BaseSpec)
3564 return clang_getNullLocation();
3565
3566 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3567 return cxloc::translateSourceLocation(getCursorContext(C),
3568 TSInfo->getTypeLoc().getBeginLoc());
3569
3570 return cxloc::translateSourceLocation(getCursorContext(C),
3571 BaseSpec->getSourceRange().getBegin());
Ted Kremenekae9e2212010-08-27 21:34:58 +00003572 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003573
Douglas Gregora93ab662010-09-10 00:22:18 +00003574 case CXCursor_LabelRef: {
3575 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3576 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3577 }
3578
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003579 case CXCursor_OverloadedDeclRef:
3580 return cxloc::translateSourceLocation(getCursorContext(C),
3581 getCursorOverloadedDeclRef(C).second);
3582
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003583 default:
3584 // FIXME: Need a way to enumerate all non-reference cases.
3585 llvm_unreachable("Missed a reference kind");
3586 }
Douglas Gregor66a58812010-01-18 22:46:11 +00003587 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003588
3589 if (clang_isExpression(C.kind))
Ted Kremenekf441baf2010-02-17 00:41:40 +00003590 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003591 getLocationFromExpr(getCursorExpr(C)));
3592
Douglas Gregora93ab662010-09-10 00:22:18 +00003593 if (clang_isStatement(C.kind))
3594 return cxloc::translateSourceLocation(getCursorContext(C),
3595 getCursorStmt(C)->getLocStart());
3596
Douglas Gregor92a524f2010-03-18 00:42:48 +00003597 if (C.kind == CXCursor_PreprocessingDirective) {
3598 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3599 return cxloc::translateSourceLocation(getCursorContext(C), L);
3600 }
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003601
3602 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor065f8d12010-03-18 17:52:52 +00003603 SourceLocation L
3604 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003605 return cxloc::translateSourceLocation(getCursorContext(C), L);
3606 }
Douglas Gregor06d6d322010-03-18 18:04:21 +00003607
3608 if (C.kind == CXCursor_MacroDefinition) {
3609 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3610 return cxloc::translateSourceLocation(getCursorContext(C), L);
3611 }
Douglas Gregor796d76a2010-10-20 22:00:55 +00003612
3613 if (C.kind == CXCursor_InclusionDirective) {
3614 SourceLocation L
3615 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3616 return cxloc::translateSourceLocation(getCursorContext(C), L);
3617 }
3618
Ted Kremenek8278a322010-05-12 06:16:13 +00003619 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003620 return clang_getNullLocation();
Douglas Gregor66a58812010-01-18 22:46:11 +00003621
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003622 Decl *D = getCursorDecl(C);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003623 SourceLocation Loc = D->getLocation();
3624 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3625 Loc = Class->getClassLoc();
Ted Kremenek818e5c12010-11-01 23:26:51 +00003626 // FIXME: Multiple variables declared in a single declaration
3627 // currently lack the information needed to correctly determine their
3628 // ranges when accounting for the type-specifier. We use context
3629 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3630 // and if so, whether it is the first decl.
3631 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3632 if (!cxcursor::isFirstInDeclGroup(C))
3633 Loc = VD->getLocation();
3634 }
3635
Douglas Gregor7bf6b8a2010-03-22 15:53:50 +00003636 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor66a58812010-01-18 22:46:11 +00003637}
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003638
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003639} // end extern "C"
3640
3641static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003642 if (clang_isReference(C.kind)) {
3643 switch (C.kind) {
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003644 case CXCursor_ObjCSuperClassRef:
3645 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003646
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003647 case CXCursor_ObjCProtocolRef:
3648 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003649
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003650 case CXCursor_ObjCClassRef:
3651 return getCursorObjCClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003652
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003653 case CXCursor_TypeRef:
3654 return getCursorTypeRef(C).second;
Douglas Gregora23e8f72010-08-31 20:37:03 +00003655
3656 case CXCursor_TemplateRef:
3657 return getCursorTemplateRef(C).second;
3658
Douglas Gregora89314e2010-08-31 23:48:11 +00003659 case CXCursor_NamespaceRef:
3660 return getCursorNamespaceRef(C).second;
Douglas Gregorf3af3112010-09-09 21:42:20 +00003661
3662 case CXCursor_MemberRef:
3663 return getCursorMemberRef(C).second;
3664
Ted Kremenekae9e2212010-08-27 21:34:58 +00003665 case CXCursor_CXXBaseSpecifier:
Douglas Gregor3478c752010-10-02 19:51:13 +00003666 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor93f89952010-01-21 16:28:34 +00003667
Douglas Gregora93ab662010-09-10 00:22:18 +00003668 case CXCursor_LabelRef:
3669 return getCursorLabelRef(C).second;
3670
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003671 case CXCursor_OverloadedDeclRef:
3672 return getCursorOverloadedDeclRef(C).second;
3673
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003674 default:
3675 // FIXME: Need a way to enumerate all non-reference cases.
3676 llvm_unreachable("Missed a reference kind");
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003677 }
3678 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003679
3680 if (clang_isExpression(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003681 return getCursorExpr(C)->getSourceRange();
Douglas Gregor562c1f92010-01-22 19:49:59 +00003682
3683 if (clang_isStatement(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003684 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003685
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003686 if (C.kind == CXCursor_PreprocessingDirective)
3687 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003688
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003689 if (C.kind == CXCursor_MacroInstantiation)
3690 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor06d6d322010-03-18 18:04:21 +00003691
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003692 if (C.kind == CXCursor_MacroDefinition)
3693 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregor796d76a2010-10-20 22:00:55 +00003694
3695 if (C.kind == CXCursor_InclusionDirective)
3696 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3697
Ted Kremenek818e5c12010-11-01 23:26:51 +00003698 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3699 Decl *D = cxcursor::getCursorDecl(C);
3700 SourceRange R = D->getSourceRange();
3701 // FIXME: Multiple variables declared in a single declaration
3702 // currently lack the information needed to correctly determine their
3703 // ranges when accounting for the type-specifier. We use context
3704 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3705 // and if so, whether it is the first decl.
3706 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3707 if (!cxcursor::isFirstInDeclGroup(C))
3708 R.setBegin(VD->getLocation());
3709 }
3710 return R;
3711 }
Douglas Gregor29ee4222010-11-17 17:14:07 +00003712 return SourceRange();
3713}
3714
3715/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3716/// the decl-specifier-seq for declarations.
3717static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3718 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3719 Decl *D = cxcursor::getCursorDecl(C);
3720 SourceRange R = D->getSourceRange();
Douglas Gregor29ee4222010-11-17 17:14:07 +00003721
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00003722 // Adjust the start of the location for declarations preceded by
3723 // declaration specifiers.
3724 SourceLocation StartLoc;
3725 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3726 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3727 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3728 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3729 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3730 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3731 }
3732
3733 if (StartLoc.isValid() && R.getBegin().isValid() &&
3734 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3735 R.setBegin(StartLoc);
3736
3737 // FIXME: Multiple variables declared in a single declaration
3738 // currently lack the information needed to correctly determine their
3739 // ranges when accounting for the type-specifier. We use context
3740 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3741 // and if so, whether it is the first decl.
3742 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3743 if (!cxcursor::isFirstInDeclGroup(C))
3744 R.setBegin(VD->getLocation());
Douglas Gregor29ee4222010-11-17 17:14:07 +00003745 }
3746
3747 return R;
3748 }
3749
3750 return getRawCursorExtent(C);
3751}
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003752
3753extern "C" {
3754
3755CXSourceRange clang_getCursorExtent(CXCursor C) {
3756 SourceRange R = getRawCursorExtent(C);
3757 if (R.isInvalid())
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003758 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003759
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003760 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003761}
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003762
3763CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003764 if (clang_isInvalid(C.kind))
3765 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003766
Ted Kremenek91554282010-11-16 08:15:36 +00003767 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003768 if (clang_isDeclaration(C.kind)) {
3769 Decl *D = getCursorDecl(C);
3770 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003771 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003772 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003773 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003774 if (ObjCForwardProtocolDecl *Protocols
3775 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003776 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00003777 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3778 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3779 return MakeCXCursor(Property, tu);
3780
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003781 return C;
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003782 }
3783
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003784 if (clang_isExpression(C.kind)) {
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003785 Expr *E = getCursorExpr(C);
3786 Decl *D = getDeclFromExpr(E);
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003787 if (D)
Ted Kremenek91554282010-11-16 08:15:36 +00003788 return MakeCXCursor(D, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003789
3790 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremenek91554282010-11-16 08:15:36 +00003791 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003792
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003793 return clang_getNullCursor();
3794 }
3795
Douglas Gregora93ab662010-09-10 00:22:18 +00003796 if (clang_isStatement(C.kind)) {
3797 Stmt *S = getCursorStmt(C);
3798 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek6f7008d2011-03-15 23:47:49 +00003799 if (LabelDecl *label = Goto->getLabel())
3800 if (LabelStmt *labelS = label->getStmt())
3801 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003802
3803 return clang_getNullCursor();
3804 }
3805
Douglas Gregor78ae2482010-03-18 18:23:03 +00003806 if (C.kind == CXCursor_MacroInstantiation) {
3807 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003808 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregor78ae2482010-03-18 18:23:03 +00003809 }
3810
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003811 if (!clang_isReference(C.kind))
3812 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003813
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003814 switch (C.kind) {
3815 case CXCursor_ObjCSuperClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003816 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003817
3818 case CXCursor_ObjCProtocolRef: {
Ted Kremenek91554282010-11-16 08:15:36 +00003819 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003820
3821 case CXCursor_ObjCClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003822 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor93f89952010-01-21 16:28:34 +00003823
Ted Kremenekf441baf2010-02-17 00:41:40 +00003824 case CXCursor_TypeRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003825 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003826
3827 case CXCursor_TemplateRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003828 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003829
Douglas Gregora89314e2010-08-31 23:48:11 +00003830 case CXCursor_NamespaceRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003831 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregora89314e2010-08-31 23:48:11 +00003832
Douglas Gregorf3af3112010-09-09 21:42:20 +00003833 case CXCursor_MemberRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003834 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregorf3af3112010-09-09 21:42:20 +00003835
Ted Kremenekae9e2212010-08-27 21:34:58 +00003836 case CXCursor_CXXBaseSpecifier: {
3837 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3838 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremenek91554282010-11-16 08:15:36 +00003839 tu ));
Ted Kremenekae9e2212010-08-27 21:34:58 +00003840 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003841
Douglas Gregora93ab662010-09-10 00:22:18 +00003842 case CXCursor_LabelRef:
3843 // FIXME: We end up faking the "parent" declaration here because we
3844 // don't want to make CXCursor larger.
3845 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremenek91554282010-11-16 08:15:36 +00003846 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3847 .getTranslationUnitDecl(),
3848 tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003849
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003850 case CXCursor_OverloadedDeclRef:
3851 return C;
3852
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003853 default:
3854 // We would prefer to enumerate all non-reference cursor kinds here.
3855 llvm_unreachable("Unhandled reference cursor kind");
3856 break;
3857 }
3858 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003859
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003860 return clang_getNullCursor();
3861}
3862
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003863CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003864 if (clang_isInvalid(C.kind))
3865 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003866
Ted Kremenek91554282010-11-16 08:15:36 +00003867 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003868
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003869 bool WasReference = false;
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003870 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003871 C = clang_getCursorReferenced(C);
3872 WasReference = true;
3873 }
3874
Douglas Gregor78ae2482010-03-18 18:23:03 +00003875 if (C.kind == CXCursor_MacroInstantiation)
3876 return clang_getCursorReferenced(C);
3877
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003878 if (!clang_isDeclaration(C.kind))
3879 return clang_getNullCursor();
3880
3881 Decl *D = getCursorDecl(C);
3882 if (!D)
3883 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003884
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003885 switch (D->getKind()) {
3886 // Declaration kinds that don't really separate the notions of
3887 // declaration and definition.
3888 case Decl::Namespace:
3889 case Decl::Typedef:
Richard Smithdda56e42011-04-15 14:24:37 +00003890 case Decl::TypeAlias:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003891 case Decl::TemplateTypeParm:
3892 case Decl::EnumConstant:
3893 case Decl::Field:
Benjamin Kramer39593702010-11-21 14:11:41 +00003894 case Decl::IndirectField:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003895 case Decl::ObjCIvar:
3896 case Decl::ObjCAtDefsField:
3897 case Decl::ImplicitParam:
3898 case Decl::ParmVar:
3899 case Decl::NonTypeTemplateParm:
3900 case Decl::TemplateTemplateParm:
3901 case Decl::ObjCCategoryImpl:
3902 case Decl::ObjCImplementation:
Abramo Bagnarad7340582010-06-05 05:09:32 +00003903 case Decl::AccessSpec:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003904 case Decl::LinkageSpec:
3905 case Decl::ObjCPropertyImpl:
3906 case Decl::FileScopeAsm:
3907 case Decl::StaticAssert:
3908 case Decl::Block:
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003909 case Decl::Label: // FIXME: Is this right??
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003910 return C;
3911
3912 // Declaration kinds that don't make any sense here, but are
3913 // nonetheless harmless.
3914 case Decl::TranslationUnit:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003915 break;
3916
3917 // Declaration kinds for which the definition is not resolvable.
3918 case Decl::UnresolvedUsingTypename:
3919 case Decl::UnresolvedUsingValue:
3920 break;
3921
3922 case Decl::UsingDirective:
Douglas Gregorfed36b12010-01-20 23:57:43 +00003923 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremenek91554282010-11-16 08:15:36 +00003924 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003925
3926 case Decl::NamespaceAlias:
Ted Kremenek91554282010-11-16 08:15:36 +00003927 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003928
3929 case Decl::Enum:
3930 case Decl::Record:
3931 case Decl::CXXRecord:
3932 case Decl::ClassTemplateSpecialization:
3933 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003934 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003935 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003936 return clang_getNullCursor();
3937
3938 case Decl::Function:
3939 case Decl::CXXMethod:
3940 case Decl::CXXConstructor:
3941 case Decl::CXXDestructor:
3942 case Decl::CXXConversion: {
3943 const FunctionDecl *Def = 0;
3944 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003945 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003946 return clang_getNullCursor();
3947 }
3948
3949 case Decl::Var: {
Sebastian Redl5ca79842010-02-01 20:16:42 +00003950 // Ask the variable if it has a definition.
3951 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003952 return MakeCXCursor(Def, TU);
Sebastian Redl5ca79842010-02-01 20:16:42 +00003953 return clang_getNullCursor();
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003954 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003955
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003956 case Decl::FunctionTemplate: {
3957 const FunctionDecl *Def = 0;
3958 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003959 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003960 return clang_getNullCursor();
3961 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003962
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003963 case Decl::ClassTemplate: {
3964 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003965 ->getDefinition())
Douglas Gregora23e8f72010-08-31 20:37:03 +00003966 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremenek91554282010-11-16 08:15:36 +00003967 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003968 return clang_getNullCursor();
3969 }
3970
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003971 case Decl::Using:
3972 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00003973 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003974
3975 case Decl::UsingShadow:
3976 return clang_getCursorDefinition(
Ted Kremenekf441baf2010-02-17 00:41:40 +00003977 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremenek91554282010-11-16 08:15:36 +00003978 TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003979
3980 case Decl::ObjCMethod: {
3981 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3982 if (Method->isThisDeclarationADefinition())
3983 return C;
3984
3985 // Dig out the method definition in the associated
3986 // @implementation, if we have it.
3987 // FIXME: The ASTs should make finding the definition easier.
3988 if (ObjCInterfaceDecl *Class
3989 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3990 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3991 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3992 Method->isInstanceMethod()))
3993 if (Def->isThisDeclarationADefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003994 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003995
3996 return clang_getNullCursor();
3997 }
3998
3999 case Decl::ObjCCategory:
4000 if (ObjCCategoryImplDecl *Impl
4001 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00004002 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004003 return clang_getNullCursor();
4004
4005 case Decl::ObjCProtocol:
4006 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
4007 return C;
4008 return clang_getNullCursor();
4009
4010 case Decl::ObjCInterface:
4011 // There are two notions of a "definition" for an Objective-C
4012 // class: the interface and its implementation. When we resolved a
4013 // reference to an Objective-C class, produce the @interface as
4014 // the definition; when we were provided with the interface,
4015 // produce the @implementation as the definition.
4016 if (WasReference) {
4017 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4018 return C;
4019 } else if (ObjCImplementationDecl *Impl
4020 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00004021 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004022 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004023
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004024 case Decl::ObjCProperty:
4025 // FIXME: We don't really know where to find the
4026 // ObjCPropertyImplDecls that implement this property.
4027 return clang_getNullCursor();
4028
4029 case Decl::ObjCCompatibleAlias:
4030 if (ObjCInterfaceDecl *Class
4031 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4032 if (!Class->isForwardDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004033 return MakeCXCursor(Class, TU);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004034
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004035 return clang_getNullCursor();
4036
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004037 case Decl::ObjCForwardProtocol:
4038 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00004039 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004040
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004041 case Decl::ObjCClass:
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00004042 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremenek91554282010-11-16 08:15:36 +00004043 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004044
4045 case Decl::Friend:
4046 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004047 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004048 return clang_getNullCursor();
4049
4050 case Decl::FriendTemplate:
4051 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004052 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004053 return clang_getNullCursor();
4054 }
4055
4056 return clang_getNullCursor();
4057}
4058
4059unsigned clang_isCursorDefinition(CXCursor C) {
4060 if (!clang_isDeclaration(C.kind))
4061 return 0;
4062
4063 return clang_getCursorDefinition(C) == C;
4064}
4065
Douglas Gregorfec4dc92010-11-19 23:44:15 +00004066CXCursor clang_getCanonicalCursor(CXCursor C) {
4067 if (!clang_isDeclaration(C.kind))
4068 return C;
4069
4070 if (Decl *D = getCursorDecl(C))
4071 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4072
4073 return C;
4074}
4075
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004076unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregorae185302010-09-16 13:54:00 +00004077 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004078 return 0;
4079
4080 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4081 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4082 return E->getNumDecls();
4083
4084 if (OverloadedTemplateStorage *S
4085 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4086 return S->size();
4087
4088 Decl *D = Storage.get<Decl*>();
4089 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis2703beb2010-11-10 05:40:41 +00004090 return Using->shadow_size();
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004091 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4092 return Classes->size();
4093 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4094 return Protocols->protocol_size();
4095
4096 return 0;
4097}
4098
4099CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregorae185302010-09-16 13:54:00 +00004100 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004101 return clang_getNullCursor();
4102
4103 if (index >= clang_getNumOverloadedDecls(cursor))
4104 return clang_getNullCursor();
4105
Ted Kremenek91554282010-11-16 08:15:36 +00004106 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004107 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4108 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremenek91554282010-11-16 08:15:36 +00004109 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004110
4111 if (OverloadedTemplateStorage *S
4112 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremenek91554282010-11-16 08:15:36 +00004113 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004114
4115 Decl *D = Storage.get<Decl*>();
4116 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4117 // FIXME: This is, unfortunately, linear time.
4118 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4119 std::advance(Pos, index);
Ted Kremenek91554282010-11-16 08:15:36 +00004120 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004121 }
4122
4123 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004124 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004125
4126 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004127 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004128
4129 return clang_getNullCursor();
4130}
4131
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00004132void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff76b8f132009-09-23 17:52:52 +00004133 const char **startBuf,
4134 const char **endBuf,
4135 unsigned *startLine,
4136 unsigned *startColumn,
4137 unsigned *endLine,
Daniel Dunbar079203f2009-12-01 03:14:51 +00004138 unsigned *endColumn) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00004139 assert(getCursorDecl(C) && "CXCursor has null decl");
4140 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff76b8f132009-09-23 17:52:52 +00004141 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4142 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004143
Steve Naroff76b8f132009-09-23 17:52:52 +00004144 SourceManager &SM = FD->getASTContext().getSourceManager();
4145 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4146 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4147 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4148 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4149 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4150 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4151}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004152
Douglas Gregor1e21cc72010-02-18 23:07:20 +00004153void clang_enableStackTraces(void) {
4154 llvm::sys::PrintStackTraceOnErrorSignal();
4155}
4156
Daniel Dunbar23420652010-11-04 01:26:29 +00004157void clang_executeOnThread(void (*fn)(void*), void *user_data,
4158 unsigned stack_size) {
4159 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4160}
4161
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004162} // end: extern "C"
Steve Naroff76b8f132009-09-23 17:52:52 +00004163
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004164//===----------------------------------------------------------------------===//
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004165// Token-based Operations.
4166//===----------------------------------------------------------------------===//
4167
4168/* CXToken layout:
4169 * int_data[0]: a CXTokenKind
4170 * int_data[1]: starting token location
4171 * int_data[2]: token length
4172 * int_data[3]: reserved
Ted Kremenekf441baf2010-02-17 00:41:40 +00004173 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004174 * otherwise unused.
4175 */
4176extern "C" {
4177
4178CXTokenKind clang_getTokenKind(CXToken CXTok) {
4179 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4180}
4181
4182CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4183 switch (clang_getTokenKind(CXTok)) {
4184 case CXToken_Identifier:
4185 case CXToken_Keyword:
4186 // We know we have an IdentifierInfo*, so use that.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004187 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4188 ->getNameStart());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004189
4190 case CXToken_Literal: {
4191 // We have stashed the starting pointer in the ptr_data field. Use it.
4192 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004193 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004194 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004195
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004196 case CXToken_Punctuation:
4197 case CXToken_Comment:
4198 break;
4199 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004200
4201 // We have to find the starting buffer pointer the hard way, by
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004202 // deconstructing the source location.
Ted Kremenek91554282010-11-16 08:15:36 +00004203 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004204 if (!CXXUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004205 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00004206
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004207 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4208 std::pair<FileID, unsigned> LocInfo
4209 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregore0fbb832010-03-16 00:06:06 +00004210 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004211 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004212 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4213 if (Invalid)
Douglas Gregor802b7762010-03-15 22:54:52 +00004214 return createCXString("");
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004215
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004216 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004217}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004218
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004219CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004220 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004221 if (!CXXUnit)
4222 return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004223
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004224 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4225 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4226}
4227
4228CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004229 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4f9c3762010-01-28 00:27:43 +00004230 if (!CXXUnit)
4231 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004232
4233 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004234 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4235}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004236
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004237void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4238 CXToken **Tokens, unsigned *NumTokens) {
4239 if (Tokens)
4240 *Tokens = 0;
4241 if (NumTokens)
4242 *NumTokens = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004243
Ted Kremenek91554282010-11-16 08:15:36 +00004244 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004245 if (!CXXUnit || !Tokens || !NumTokens)
4246 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004247
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004248 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4249
Daniel Dunbar80daf532010-02-14 08:31:57 +00004250 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004251 if (R.isInvalid())
4252 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004253
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004254 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4255 std::pair<FileID, unsigned> BeginLocInfo
4256 = SourceMgr.getDecomposedLoc(R.getBegin());
4257 std::pair<FileID, unsigned> EndLocInfo
4258 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004259
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004260 // Cannot tokenize across files.
4261 if (BeginLocInfo.first != EndLocInfo.first)
4262 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004263
4264 // Create a lexer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004265 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004266 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004267 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor554e0b12010-03-16 20:26:15 +00004268 if (Invalid)
4269 return;
Douglas Gregor802b7762010-03-15 22:54:52 +00004270
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004271 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4272 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004273 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004274 Lex.SetCommentRetentionState(true);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004275
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004276 // Lex tokens until we hit the end of the range.
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004277 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004278 llvm::SmallVector<CXToken, 32> CXTokens;
4279 Token Tok;
David Chisnall1822d1f2010-10-13 21:44:48 +00004280 bool previousWasAt = false;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004281 do {
4282 // Lex the next token
4283 Lex.LexFromRawLexer(Tok);
4284 if (Tok.is(tok::eof))
4285 break;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004286
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004287 // Initialize the CXToken.
4288 CXToken CXTok;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004289
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004290 // - Common fields
4291 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4292 CXTok.int_data[2] = Tok.getLength();
4293 CXTok.int_data[3] = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004294
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004295 // - Kind-specific fields
4296 if (Tok.isLiteral()) {
4297 CXTok.int_data[0] = CXToken_Literal;
4298 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004299 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregor802b7762010-03-15 22:54:52 +00004300 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004301 IdentifierInfo *II
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004302 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004303
David Chisnall1822d1f2010-10-13 21:44:48 +00004304 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004305 CXTok.int_data[0] = CXToken_Keyword;
4306 }
4307 else {
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004308 CXTok.int_data[0] = Tok.is(tok::identifier)
4309 ? CXToken_Identifier
4310 : CXToken_Keyword;
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004311 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004312 CXTok.ptr_data = II;
4313 } else if (Tok.is(tok::comment)) {
4314 CXTok.int_data[0] = CXToken_Comment;
4315 CXTok.ptr_data = 0;
4316 } else {
4317 CXTok.int_data[0] = CXToken_Punctuation;
4318 CXTok.ptr_data = 0;
4319 }
4320 CXTokens.push_back(CXTok);
David Chisnall1822d1f2010-10-13 21:44:48 +00004321 previousWasAt = Tok.is(tok::at);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004322 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004323
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004324 if (CXTokens.empty())
4325 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004326
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004327 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4328 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4329 *NumTokens = CXTokens.size();
4330}
Douglas Gregor61656112010-01-26 18:31:56 +00004331
Ted Kremenek63ac5992010-05-05 00:55:15 +00004332void clang_disposeTokens(CXTranslationUnit TU,
4333 CXToken *Tokens, unsigned NumTokens) {
4334 free(Tokens);
4335}
4336
4337} // end: extern "C"
4338
4339//===----------------------------------------------------------------------===//
4340// Token annotation APIs.
4341//===----------------------------------------------------------------------===//
4342
Douglas Gregor61656112010-01-26 18:31:56 +00004343typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenek680fe512010-05-05 00:55:23 +00004344static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4345 CXCursor parent,
4346 CXClientData client_data);
Ted Kremenek63ac5992010-05-05 00:55:15 +00004347namespace {
4348class AnnotateTokensWorker {
4349 AnnotateTokensData &Annotated;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004350 CXToken *Tokens;
4351 CXCursor *Cursors;
4352 unsigned NumTokens;
Ted Kremenek680fe512010-05-05 00:55:23 +00004353 unsigned TokIdx;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004354 unsigned PreprocessingTokIdx;
Ted Kremenek680fe512010-05-05 00:55:23 +00004355 CursorVisitor AnnotateVis;
4356 SourceManager &SrcMgr;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004357 bool HasContextSensitiveKeywords;
4358
Ted Kremenek680fe512010-05-05 00:55:23 +00004359 bool MoreTokens() const { return TokIdx < NumTokens; }
4360 unsigned NextToken() const { return TokIdx; }
4361 void AdvanceToken() { ++TokIdx; }
4362 SourceLocation GetTokenLoc(unsigned tokI) {
4363 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4364 }
4365
Ted Kremenek63ac5992010-05-05 00:55:15 +00004366public:
Ted Kremenek458c2f12010-05-05 00:55:17 +00004367 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenek680fe512010-05-05 00:55:23 +00004368 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremenek91554282010-11-16 08:15:36 +00004369 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek458c2f12010-05-05 00:55:17 +00004370 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004371 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremenek91554282010-11-16 08:15:36 +00004372 AnnotateVis(tu,
4373 AnnotateTokensVisitor, this,
Douglas Gregorc2b97992011-03-16 23:23:30 +00004374 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf2f08062011-03-08 17:10:18 +00004375 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4376 HasContextSensitiveKeywords(false) { }
Ted Kremenek458c2f12010-05-05 00:55:17 +00004377
Ted Kremenek680fe512010-05-05 00:55:23 +00004378 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004379 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenek680fe512010-05-05 00:55:23 +00004380 void AnnotateTokens(CXCursor parent);
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004381 void AnnotateTokens() {
Ted Kremenek91554282010-11-16 08:15:36 +00004382 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004383 }
Douglas Gregorf2f08062011-03-08 17:10:18 +00004384
4385 /// \brief Determine whether the annotator saw any cursors that have
4386 /// context-sensitive keywords.
4387 bool hasContextSensitiveKeywords() const {
4388 return HasContextSensitiveKeywords;
4389 }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004390};
4391}
Douglas Gregor61656112010-01-26 18:31:56 +00004392
Ted Kremenek680fe512010-05-05 00:55:23 +00004393void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4394 // Walk the AST within the region of interest, annotating tokens
4395 // along the way.
4396 VisitChildren(parent);
Ted Kremenek458c2f12010-05-05 00:55:17 +00004397
Ted Kremenek680fe512010-05-05 00:55:23 +00004398 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4399 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004400 if (Pos != Annotated.end() &&
4401 (clang_isInvalid(Cursors[I].kind) ||
4402 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenek680fe512010-05-05 00:55:23 +00004403 Cursors[I] = Pos->second;
4404 }
4405
4406 // Finish up annotating any tokens left.
4407 if (!MoreTokens())
4408 return;
4409
4410 const CXCursor &C = clang_getNullCursor();
4411 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4412 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4413 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004414 }
4415}
4416
Ted Kremenek63ac5992010-05-05 00:55:15 +00004417enum CXChildVisitResult
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004418AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004419 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004420 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004421 if (cursorRange.isInvalid())
4422 return CXChildVisit_Recurse;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004423
4424 if (!HasContextSensitiveKeywords) {
4425 // Objective-C properties can have context-sensitive keywords.
4426 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4427 if (ObjCPropertyDecl *Property
4428 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4429 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4430 }
4431 // Objective-C methods can have context-sensitive keywords.
4432 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4433 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4434 if (ObjCMethodDecl *Method
4435 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4436 if (Method->getObjCDeclQualifier())
4437 HasContextSensitiveKeywords = true;
4438 else {
4439 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4440 PEnd = Method->param_end();
4441 P != PEnd; ++P) {
4442 if ((*P)->getObjCDeclQualifier()) {
4443 HasContextSensitiveKeywords = true;
4444 break;
4445 }
4446 }
4447 }
4448 }
4449 }
4450 // C++ methods can have context-sensitive keywords.
4451 else if (cursor.kind == CXCursor_CXXMethod) {
4452 if (CXXMethodDecl *Method
4453 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4454 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4455 HasContextSensitiveKeywords = true;
4456 }
4457 }
4458 // C++ classes can have context-sensitive keywords.
4459 else if (cursor.kind == CXCursor_StructDecl ||
4460 cursor.kind == CXCursor_ClassDecl ||
4461 cursor.kind == CXCursor_ClassTemplate ||
4462 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4463 if (Decl *D = getCursorDecl(cursor))
4464 if (D->hasAttr<FinalAttr>())
4465 HasContextSensitiveKeywords = true;
4466 }
4467 }
4468
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004469 if (clang_isPreprocessing(cursor.kind)) {
4470 // For macro instantiations, just note where the beginning of the macro
4471 // instantiation occurs.
4472 if (cursor.kind == CXCursor_MacroInstantiation) {
4473 Annotated[Loc.int_data] = cursor;
4474 return CXChildVisit_Recurse;
4475 }
4476
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004477 // Items in the preprocessing record are kept separate from items in
4478 // declarations, so we keep a separate token index.
4479 unsigned SavedTokIdx = TokIdx;
4480 TokIdx = PreprocessingTokIdx;
4481
4482 // Skip tokens up until we catch up to the beginning of the preprocessing
4483 // entry.
4484 while (MoreTokens()) {
4485 const unsigned I = NextToken();
4486 SourceLocation TokLoc = GetTokenLoc(I);
4487 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4488 case RangeBefore:
4489 AdvanceToken();
4490 continue;
4491 case RangeAfter:
4492 case RangeOverlap:
4493 break;
4494 }
4495 break;
4496 }
4497
4498 // Look at all of the tokens within this range.
4499 while (MoreTokens()) {
4500 const unsigned I = NextToken();
4501 SourceLocation TokLoc = GetTokenLoc(I);
4502 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4503 case RangeBefore:
4504 assert(0 && "Infeasible");
4505 case RangeAfter:
4506 break;
4507 case RangeOverlap:
4508 Cursors[I] = cursor;
4509 AdvanceToken();
4510 continue;
4511 }
4512 break;
4513 }
4514
4515 // Save the preprocessing token index; restore the non-preprocessing
4516 // token index.
4517 PreprocessingTokIdx = TokIdx;
4518 TokIdx = SavedTokIdx;
Douglas Gregor61656112010-01-26 18:31:56 +00004519 return CXChildVisit_Recurse;
4520 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004521
Ted Kremenek680fe512010-05-05 00:55:23 +00004522 if (cursorRange.isInvalid())
4523 return CXChildVisit_Continue;
Ted Kremenek5d616142010-05-12 05:29:33 +00004524
Ted Kremenek680fe512010-05-05 00:55:23 +00004525 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4526
Ted Kremenek5d616142010-05-12 05:29:33 +00004527 // Adjust the annotated range based specific declarations.
4528 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4529 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek49be9e02010-05-18 21:09:07 +00004530 Decl *D = cxcursor::getCursorDecl(cursor);
4531 // Don't visit synthesized ObjC methods, since they have no syntatic
4532 // representation in the source.
4533 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4534 if (MD->isSynthesized())
4535 return CXChildVisit_Continue;
4536 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004537
4538 SourceLocation StartLoc;
Ted Kremenek49be9e02010-05-18 21:09:07 +00004539 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004540 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4541 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4542 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4543 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4544 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremenek5d616142010-05-12 05:29:33 +00004545 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004546
4547 if (StartLoc.isValid() && L.isValid() &&
4548 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4549 cursorRange.setBegin(StartLoc);
Ted Kremenek5d616142010-05-12 05:29:33 +00004550 }
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004551
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004552 // If the location of the cursor occurs within a macro instantiation, record
4553 // the spelling location of the cursor in our annotation map. We can then
4554 // paper over the token labelings during a post-processing step to try and
4555 // get cursor mappings for tokens that are the *arguments* of a macro
4556 // instantiation.
4557 if (L.isMacroID()) {
4558 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4559 // Only invalidate the old annotation if it isn't part of a preprocessing
4560 // directive. Here we assume that the default construction of CXCursor
4561 // results in CXCursor.kind being an initialized value (i.e., 0). If
4562 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004563
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004564 CXCursor &oldC = Annotated[rawEncoding];
4565 if (!clang_isPreprocessing(oldC.kind))
4566 oldC = cursor;
4567 }
4568
Ted Kremenek680fe512010-05-05 00:55:23 +00004569 const enum CXCursorKind K = clang_getCursorKind(parent);
4570 const CXCursor updateC =
Ted Kremenek65b2cc02010-08-25 22:16:02 +00004571 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4572 ? clang_getNullCursor() : parent;
Ted Kremenek680fe512010-05-05 00:55:23 +00004573
4574 while (MoreTokens()) {
4575 const unsigned I = NextToken();
4576 SourceLocation TokLoc = GetTokenLoc(I);
4577 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4578 case RangeBefore:
4579 Cursors[I] = updateC;
4580 AdvanceToken();
4581 continue;
4582 case RangeAfter:
Ted Kremenek680fe512010-05-05 00:55:23 +00004583 case RangeOverlap:
4584 break;
4585 }
4586 break;
4587 }
4588
4589 // Visit children to get their cursor information.
4590 const unsigned BeforeChildren = NextToken();
4591 VisitChildren(cursor);
4592 const unsigned AfterChildren = NextToken();
4593
4594 // Adjust 'Last' to the last token within the extent of the cursor.
4595 while (MoreTokens()) {
4596 const unsigned I = NextToken();
4597 SourceLocation TokLoc = GetTokenLoc(I);
4598 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4599 case RangeBefore:
4600 assert(0 && "Infeasible");
4601 case RangeAfter:
4602 break;
4603 case RangeOverlap:
4604 Cursors[I] = updateC;
4605 AdvanceToken();
4606 continue;
4607 }
4608 break;
4609 }
4610 const unsigned Last = NextToken();
Ted Kremenek63ac5992010-05-05 00:55:15 +00004611
Ted Kremenek680fe512010-05-05 00:55:23 +00004612 // Scan the tokens that are at the beginning of the cursor, but are not
4613 // capture by the child cursors.
4614
4615 // For AST elements within macros, rely on a post-annotate pass to
4616 // to correctly annotate the tokens with cursors. Otherwise we can
4617 // get confusing results of having tokens that map to cursors that really
4618 // are expanded by an instantiation.
4619 if (L.isMacroID())
4620 cursor = clang_getNullCursor();
4621
4622 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4623 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4624 break;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004625
Ted Kremenek680fe512010-05-05 00:55:23 +00004626 Cursors[I] = cursor;
4627 }
4628 // Scan the tokens that are at the end of the cursor, but are not captured
4629 // but the child cursors.
4630 for (unsigned I = AfterChildren; I != Last; ++I)
4631 Cursors[I] = cursor;
4632
4633 TokIdx = Last;
4634 return CXChildVisit_Continue;
Douglas Gregor61656112010-01-26 18:31:56 +00004635}
4636
Ted Kremenek63ac5992010-05-05 00:55:15 +00004637static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4638 CXCursor parent,
4639 CXClientData client_data) {
4640 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4641}
4642
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004643namespace {
4644 struct clang_annotateTokens_Data {
4645 CXTranslationUnit TU;
4646 ASTUnit *CXXUnit;
4647 CXToken *Tokens;
4648 unsigned NumTokens;
4649 CXCursor *Cursors;
4650 };
4651}
4652
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004653// This gets run a separate thread to avoid stack blowout.
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004654static void clang_annotateTokensImpl(void *UserData) {
4655 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4656 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4657 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4658 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4659 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4660
4661 // Determine the region of interest, which contains all of the tokens.
4662 SourceRange RegionOfInterest;
4663 RegionOfInterest.setBegin(
4664 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4665 RegionOfInterest.setEnd(
4666 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4667 Tokens[NumTokens-1])));
4668
4669 // A mapping from the source locations found when re-lexing or traversing the
4670 // region of interest to the corresponding cursors.
4671 AnnotateTokensData Annotated;
4672
4673 // Relex the tokens within the source range to look for preprocessing
4674 // directives.
4675 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4676 std::pair<FileID, unsigned> BeginLocInfo
4677 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4678 std::pair<FileID, unsigned> EndLocInfo
4679 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4680
4681 llvm::StringRef Buffer;
4682 bool Invalid = false;
4683 if (BeginLocInfo.first == EndLocInfo.first &&
4684 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4685 !Invalid) {
4686 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4687 CXXUnit->getASTContext().getLangOptions(),
4688 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4689 Buffer.end());
4690 Lex.SetCommentRetentionState(true);
4691
4692 // Lex tokens in raw mode until we hit the end of the range, to avoid
4693 // entering #includes or expanding macros.
4694 while (true) {
4695 Token Tok;
4696 Lex.LexFromRawLexer(Tok);
4697
4698 reprocess:
4699 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4700 // We have found a preprocessing directive. Gobble it up so that we
4701 // don't see it while preprocessing these tokens later, but keep track
4702 // of all of the token locations inside this preprocessing directive so
4703 // that we can annotate them appropriately.
4704 //
4705 // FIXME: Some simple tests here could identify macro definitions and
4706 // #undefs, to provide specific cursor kinds for those.
4707 llvm::SmallVector<SourceLocation, 32> Locations;
4708 do {
4709 Locations.push_back(Tok.getLocation());
4710 Lex.LexFromRawLexer(Tok);
4711 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4712
4713 using namespace cxcursor;
4714 CXCursor Cursor
4715 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4716 Locations.back()),
4717 TU);
4718 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4719 Annotated[Locations[I].getRawEncoding()] = Cursor;
4720 }
4721
4722 if (Tok.isAtStartOfLine())
4723 goto reprocess;
4724
4725 continue;
4726 }
4727
4728 if (Tok.is(tok::eof))
4729 break;
4730 }
4731 }
4732
4733 // Annotate all of the source locations in the region of interest that map to
4734 // a specific cursor.
4735 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4736 TU, RegionOfInterest);
4737
4738 // FIXME: We use a ridiculous stack size here because the data-recursion
4739 // algorithm uses a large stack frame than the non-data recursive version,
4740 // and AnnotationTokensWorker currently transforms the data-recursion
4741 // algorithm back into a traditional recursion by explicitly calling
4742 // VisitChildren(). We will need to remove this explicit recursive call.
4743 W.AnnotateTokens();
4744
4745 // If we ran into any entities that involve context-sensitive keywords,
4746 // take another pass through the tokens to mark them as such.
4747 if (W.hasContextSensitiveKeywords()) {
4748 for (unsigned I = 0; I != NumTokens; ++I) {
4749 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4750 continue;
4751
4752 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4753 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4754 if (ObjCPropertyDecl *Property
4755 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4756 if (Property->getPropertyAttributesAsWritten() != 0 &&
4757 llvm::StringSwitch<bool>(II->getName())
4758 .Case("readonly", true)
4759 .Case("assign", true)
4760 .Case("readwrite", true)
4761 .Case("retain", true)
4762 .Case("copy", true)
4763 .Case("nonatomic", true)
4764 .Case("atomic", true)
4765 .Case("getter", true)
4766 .Case("setter", true)
4767 .Default(false))
4768 Tokens[I].int_data[0] = CXToken_Keyword;
4769 }
4770 continue;
4771 }
4772
4773 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4774 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4775 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4776 if (llvm::StringSwitch<bool>(II->getName())
4777 .Case("in", true)
4778 .Case("out", true)
4779 .Case("inout", true)
4780 .Case("oneway", true)
4781 .Case("bycopy", true)
4782 .Case("byref", true)
4783 .Default(false))
4784 Tokens[I].int_data[0] = CXToken_Keyword;
4785 continue;
4786 }
4787
4788 if (Cursors[I].kind == CXCursor_CXXMethod) {
4789 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4790 if (CXXMethodDecl *Method
4791 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4792 if ((Method->hasAttr<FinalAttr>() ||
4793 Method->hasAttr<OverrideAttr>()) &&
4794 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4795 llvm::StringSwitch<bool>(II->getName())
4796 .Case("final", true)
4797 .Case("override", true)
4798 .Default(false))
4799 Tokens[I].int_data[0] = CXToken_Keyword;
4800 }
4801 continue;
4802 }
4803
4804 if (Cursors[I].kind == CXCursor_ClassDecl ||
4805 Cursors[I].kind == CXCursor_StructDecl ||
4806 Cursors[I].kind == CXCursor_ClassTemplate) {
4807 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4808 if (II->getName() == "final") {
4809 // We have to be careful with 'final', since it could be the name
4810 // of a member class rather than the context-sensitive keyword.
4811 // So, check whether the cursor associated with this
4812 Decl *D = getCursorDecl(Cursors[I]);
4813 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4814 if ((Record->hasAttr<FinalAttr>()) &&
4815 Record->getIdentifier() != II)
4816 Tokens[I].int_data[0] = CXToken_Keyword;
4817 } else if (ClassTemplateDecl *ClassTemplate
4818 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4819 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4820 if ((Record->hasAttr<FinalAttr>()) &&
4821 Record->getIdentifier() != II)
4822 Tokens[I].int_data[0] = CXToken_Keyword;
4823 }
4824 }
4825 continue;
4826 }
4827 }
4828 }
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004829}
4830
Ted Kremenek63ac5992010-05-05 00:55:15 +00004831extern "C" {
4832
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004833void clang_annotateTokens(CXTranslationUnit TU,
4834 CXToken *Tokens, unsigned NumTokens,
4835 CXCursor *Cursors) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004836
4837 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor61656112010-01-26 18:31:56 +00004838 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004839
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004840 // Any token we don't specifically annotate will have a NULL cursor.
4841 CXCursor C = clang_getNullCursor();
4842 for (unsigned I = 0; I != NumTokens; ++I)
4843 Cursors[I] = C;
4844
Ted Kremenek91554282010-11-16 08:15:36 +00004845 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004846 if (!CXXUnit)
Douglas Gregor61656112010-01-26 18:31:56 +00004847 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004848
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004849 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004850
4851 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004852 llvm::CrashRecoveryContext CRC;
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004853 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenekca817a3c2010-11-14 17:47:35 +00004854 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004855 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4856 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004857}
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004858
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004859} // end: extern "C"
4860
4861//===----------------------------------------------------------------------===//
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004862// Operations for querying linkage of a cursor.
4863//===----------------------------------------------------------------------===//
4864
4865extern "C" {
4866CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor5272e802010-03-19 05:22:59 +00004867 if (!clang_isDeclaration(cursor.kind))
4868 return CXLinkage_Invalid;
4869
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004870 Decl *D = cxcursor::getCursorDecl(cursor);
4871 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4872 switch (ND->getLinkage()) {
4873 case NoLinkage: return CXLinkage_NoLinkage;
4874 case InternalLinkage: return CXLinkage_Internal;
4875 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4876 case ExternalLinkage: return CXLinkage_External;
4877 };
4878
4879 return CXLinkage_Invalid;
4880}
4881} // end: extern "C"
4882
4883//===----------------------------------------------------------------------===//
Ted Kremenek4ed29252010-04-12 21:22:16 +00004884// Operations for querying language of a cursor.
4885//===----------------------------------------------------------------------===//
4886
4887static CXLanguageKind getDeclLanguage(const Decl *D) {
4888 switch (D->getKind()) {
4889 default:
4890 break;
4891 case Decl::ImplicitParam:
4892 case Decl::ObjCAtDefsField:
4893 case Decl::ObjCCategory:
4894 case Decl::ObjCCategoryImpl:
4895 case Decl::ObjCClass:
4896 case Decl::ObjCCompatibleAlias:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004897 case Decl::ObjCForwardProtocol:
4898 case Decl::ObjCImplementation:
4899 case Decl::ObjCInterface:
4900 case Decl::ObjCIvar:
4901 case Decl::ObjCMethod:
4902 case Decl::ObjCProperty:
4903 case Decl::ObjCPropertyImpl:
4904 case Decl::ObjCProtocol:
4905 return CXLanguage_ObjC;
4906 case Decl::CXXConstructor:
4907 case Decl::CXXConversion:
4908 case Decl::CXXDestructor:
4909 case Decl::CXXMethod:
4910 case Decl::CXXRecord:
4911 case Decl::ClassTemplate:
4912 case Decl::ClassTemplatePartialSpecialization:
4913 case Decl::ClassTemplateSpecialization:
4914 case Decl::Friend:
4915 case Decl::FriendTemplate:
4916 case Decl::FunctionTemplate:
4917 case Decl::LinkageSpec:
4918 case Decl::Namespace:
4919 case Decl::NamespaceAlias:
4920 case Decl::NonTypeTemplateParm:
4921 case Decl::StaticAssert:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004922 case Decl::TemplateTemplateParm:
4923 case Decl::TemplateTypeParm:
4924 case Decl::UnresolvedUsingTypename:
4925 case Decl::UnresolvedUsingValue:
4926 case Decl::Using:
4927 case Decl::UsingDirective:
4928 case Decl::UsingShadow:
4929 return CXLanguage_CPlusPlus;
4930 }
4931
4932 return CXLanguage_C;
4933}
4934
4935extern "C" {
Douglas Gregorf757a122010-08-23 23:00:57 +00004936
4937enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4938 if (clang_isDeclaration(cursor.kind))
4939 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004940 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregorf757a122010-08-23 23:00:57 +00004941 return CXAvailability_Available;
4942
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004943 switch (D->getAvailability()) {
4944 case AR_Available:
4945 case AR_NotYetIntroduced:
4946 return CXAvailability_Available;
4947
4948 case AR_Deprecated:
Douglas Gregorf757a122010-08-23 23:00:57 +00004949 return CXAvailability_Deprecated;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004950
4951 case AR_Unavailable:
4952 return CXAvailability_NotAvailable;
4953 }
Douglas Gregorf757a122010-08-23 23:00:57 +00004954 }
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004955
Douglas Gregorf757a122010-08-23 23:00:57 +00004956 return CXAvailability_Available;
4957}
4958
Ted Kremenek4ed29252010-04-12 21:22:16 +00004959CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4960 if (clang_isDeclaration(cursor.kind))
4961 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4962
4963 return CXLanguage_Invalid;
4964}
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004965
4966 /// \brief If the given cursor is the "templated" declaration
4967 /// descibing a class or function template, return the class or
4968 /// function template.
4969static Decl *maybeGetTemplateCursor(Decl *D) {
4970 if (!D)
4971 return 0;
4972
4973 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4974 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4975 return FunTmpl;
4976
4977 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4978 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4979 return ClassTmpl;
4980
4981 return D;
4982}
4983
Douglas Gregor0576ce72010-09-22 21:22:29 +00004984CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4985 if (clang_isDeclaration(cursor.kind)) {
4986 if (Decl *D = getCursorDecl(cursor)) {
4987 DeclContext *DC = D->getDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004988 if (!DC)
4989 return clang_getNullCursor();
4990
4991 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4992 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004993 }
4994 }
4995
4996 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4997 if (Decl *D = getCursorDecl(cursor))
Ted Kremenek91554282010-11-16 08:15:36 +00004998 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004999 }
5000
5001 return clang_getNullCursor();
5002}
5003
5004CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5005 if (clang_isDeclaration(cursor.kind)) {
5006 if (Decl *D = getCursorDecl(cursor)) {
5007 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00005008 if (!DC)
5009 return clang_getNullCursor();
5010
5011 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5012 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00005013 }
5014 }
5015
5016 // FIXME: Note that we can't easily compute the lexical context of a
5017 // statement or expression, so we return nothing.
5018 return clang_getNullCursor();
5019}
5020
Douglas Gregor99a26af2010-10-01 20:25:15 +00005021static void CollectOverriddenMethods(DeclContext *Ctx,
5022 ObjCMethodDecl *Method,
5023 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5024 if (!Ctx)
5025 return;
5026
5027 // If we have a class or category implementation, jump straight to the
5028 // interface.
5029 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5030 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5031
5032 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5033 if (!Container)
5034 return;
5035
5036 // Check whether we have a matching method at this level.
5037 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5038 Method->isInstanceMethod()))
5039 if (Method != Overridden) {
5040 // We found an override at this level; there is no need to look
5041 // into other protocols or categories.
5042 Methods.push_back(Overridden);
5043 return;
5044 }
5045
5046 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5047 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5048 PEnd = Protocol->protocol_end();
5049 P != PEnd; ++P)
5050 CollectOverriddenMethods(*P, Method, Methods);
5051 }
5052
5053 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5054 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5055 PEnd = Category->protocol_end();
5056 P != PEnd; ++P)
5057 CollectOverriddenMethods(*P, Method, Methods);
5058 }
5059
5060 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5061 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5062 PEnd = Interface->protocol_end();
5063 P != PEnd; ++P)
5064 CollectOverriddenMethods(*P, Method, Methods);
5065
5066 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5067 Category; Category = Category->getNextClassCategory())
5068 CollectOverriddenMethods(Category, Method, Methods);
5069
5070 // We only look into the superclass if we haven't found anything yet.
5071 if (Methods.empty())
5072 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5073 return CollectOverriddenMethods(Super, Method, Methods);
5074 }
5075}
5076
5077void clang_getOverriddenCursors(CXCursor cursor,
5078 CXCursor **overridden,
5079 unsigned *num_overridden) {
5080 if (overridden)
5081 *overridden = 0;
5082 if (num_overridden)
5083 *num_overridden = 0;
5084 if (!overridden || !num_overridden)
5085 return;
5086
5087 if (!clang_isDeclaration(cursor.kind))
5088 return;
5089
5090 Decl *D = getCursorDecl(cursor);
5091 if (!D)
5092 return;
5093
5094 // Handle C++ member functions.
Ted Kremenek91554282010-11-16 08:15:36 +00005095 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005096 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5097 *num_overridden = CXXMethod->size_overridden_methods();
5098 if (!*num_overridden)
5099 return;
5100
5101 *overridden = new CXCursor [*num_overridden];
5102 unsigned I = 0;
5103 for (CXXMethodDecl::method_iterator
5104 M = CXXMethod->begin_overridden_methods(),
5105 MEnd = CXXMethod->end_overridden_methods();
5106 M != MEnd; (void)++M, ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00005107 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005108 return;
5109 }
5110
5111 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5112 if (!Method)
5113 return;
5114
5115 // Handle Objective-C methods.
5116 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5117 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5118
5119 if (Methods.empty())
5120 return;
5121
5122 *num_overridden = Methods.size();
5123 *overridden = new CXCursor [Methods.size()];
5124 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00005125 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005126}
5127
5128void clang_disposeOverriddenCursors(CXCursor *overridden) {
5129 delete [] overridden;
5130}
5131
Douglas Gregor796d76a2010-10-20 22:00:55 +00005132CXFile clang_getIncludedFile(CXCursor cursor) {
5133 if (cursor.kind != CXCursor_InclusionDirective)
5134 return 0;
5135
5136 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5137 return (void *)ID->getFile();
5138}
5139
Ted Kremenek4ed29252010-04-12 21:22:16 +00005140} // end: extern "C"
5141
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005142
5143//===----------------------------------------------------------------------===//
5144// C++ AST instrospection.
5145//===----------------------------------------------------------------------===//
5146
5147extern "C" {
5148unsigned clang_CXXMethod_isStatic(CXCursor C) {
5149 if (!clang_isDeclaration(C.kind))
5150 return 0;
Douglas Gregorf11309e2010-08-31 22:12:17 +00005151
5152 CXXMethodDecl *Method = 0;
5153 Decl *D = cxcursor::getCursorDecl(C);
5154 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5155 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5156 else
5157 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5158 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek0ed75492010-05-17 20:12:45 +00005159}
Ted Kremeneka10f1282010-05-18 22:32:15 +00005160
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005161} // end: extern "C"
5162
Ted Kremenek4ed29252010-04-12 21:22:16 +00005163//===----------------------------------------------------------------------===//
Ted Kremeneka5940822010-08-26 01:42:22 +00005164// Attribute introspection.
5165//===----------------------------------------------------------------------===//
5166
5167extern "C" {
5168CXType clang_getIBOutletCollectionType(CXCursor C) {
5169 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremenek91554282010-11-16 08:15:36 +00005170 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005171
5172 IBOutletCollectionAttr *A =
5173 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5174
Douglas Gregorc81a7a22011-03-06 18:55:32 +00005175 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005176}
5177} // end: extern "C"
5178
5179//===----------------------------------------------------------------------===//
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005180// Misc. utility functions.
5181//===----------------------------------------------------------------------===//
Ted Kremenekf441baf2010-02-17 00:41:40 +00005182
Daniel Dunbar087c3a32010-11-05 17:21:46 +00005183/// Default to using an 8 MB stack size on "safety" threads.
5184static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005185
5186namespace clang {
5187
5188bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenekca817a3c2010-11-14 17:47:35 +00005189 void (*Fn)(void*), void *UserData,
5190 unsigned Size) {
5191 if (!Size)
5192 Size = GetSafetyThreadStackSize();
5193 if (Size)
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005194 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5195 return CRC.RunSafely(Fn, UserData);
5196}
5197
5198unsigned GetSafetyThreadStackSize() {
5199 return SafetyStackThreadSize;
5200}
5201
5202void SetSafetyThreadStackSize(unsigned Value) {
5203 SafetyStackThreadSize = Value;
5204}
5205
5206}
5207
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005208extern "C" {
5209
Ted Kremeneka3e65702010-02-12 22:54:40 +00005210CXString clang_getClangVersion() {
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00005211 return createCXString(getClangFullVersion());
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005212}
5213
5214} // end: extern "C"