blob: 0aba04a48c6f3f3cff370939c0c55e13a38e37a9 [file] [log] [blame]
Ted Kremenekb60d87c2009-08-26 22:36:44 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00007//
Ted Kremenekb60d87c2009-08-26 22:36:44 +00008//===----------------------------------------------------------------------===//
9//
Ted Kremenek0ec2cca2010-01-05 19:32:54 +000010// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
Ted Kremenekb60d87c2009-08-26 22:36:44 +000012//
13//===----------------------------------------------------------------------===//
14
Ted Kremenek0ec2cca2010-01-05 19:32:54 +000015#include "CIndexer.h"
Ted Kremenek87553c42010-01-15 20:35:54 +000016#include "CXCursor.h"
Ted Kremenek7df92ae2010-11-17 23:24:11 +000017#include "CXTranslationUnit.h"
Ted Kremenek4b4f3692010-11-16 01:56:27 +000018#include "CXString.h"
Ted Kremeneka5940822010-08-26 01:42:22 +000019#include "CXType.h"
Ted Kremenek97a45372010-01-25 22:34:44 +000020#include "CXSourceLocation.h"
Douglas Gregor4f9c3762010-01-28 00:27:43 +000021#include "CIndexDiagnostic.h"
Ted Kremenek0ec2cca2010-01-05 19:32:54 +000022
Ted Kremenekc0f3f722010-01-22 22:44:15 +000023#include "clang/Basic/Version.h"
Douglas Gregorba965fb2010-01-28 00:56:43 +000024
Steve Naroffa1c72842009-08-28 15:28:48 +000025#include "clang/AST/DeclVisitor.h"
Steve Naroff66af1ae2009-09-22 19:25:29 +000026#include "clang/AST/StmtVisitor.h"
Douglas Gregor93f89952010-01-21 16:28:34 +000027#include "clang/AST/TypeLocVisitor.h"
Benjamin Kramer064414532010-04-12 19:45:50 +000028#include "clang/Basic/Diagnostic.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
Douglas Gregorba965fb2010-01-28 00:56:43 +000031#include "clang/Frontend/FrontendDiagnostic.h"
Ted Kremenek2a43fd52010-01-06 23:43:31 +000032#include "clang/Lex/Lexer.h"
Benjamin Kramer064414532010-04-12 19:45:50 +000033#include "clang/Lex/PreprocessingRecord.h"
Douglas Gregor562c1f92010-01-22 19:49:59 +000034#include "clang/Lex/Preprocessor.h"
Douglas Gregorf3af3112010-09-09 21:42:20 +000035#include "llvm/ADT/STLExtras.h"
Ted Kremenekd40a4392010-11-02 23:10:24 +000036#include "llvm/ADT/Optional.h"
Douglas Gregorf2f08062011-03-08 17:10:18 +000037#include "llvm/ADT/StringSwitch.h"
Ted Kremenekd40a4392010-11-02 23:10:24 +000038#include "clang/Analysis/Support/SaveAndRestore.h"
Daniel Dunbarc91f2ff2010-08-18 18:43:14 +000039#include "llvm/Support/CrashRecoveryContext.h"
Daniel Dunbara5af410d2010-10-08 19:30:33 +000040#include "llvm/Support/PrettyStackTrace.h"
Douglas Gregord3d923a2009-10-16 21:24:31 +000041#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor97c75712010-10-02 22:49:11 +000042#include "llvm/Support/raw_ostream.h"
Douglas Gregor8ef4c802010-08-09 21:00:09 +000043#include "llvm/Support/Timer.h"
Michael J. Spencer8aaf4992010-11-29 18:12:39 +000044#include "llvm/Support/Mutex.h"
45#include "llvm/Support/Program.h"
46#include "llvm/Support/Signals.h"
47#include "llvm/Support/Threading.h"
Ted Kremenekacd03f62010-11-15 23:11:54 +000048#include "llvm/Support/Compiler.h"
Ted Kremenek428c6372009-10-19 21:44:57 +000049
Steve Naroffa1c72842009-08-28 15:28:48 +000050using namespace clang;
Ted Kremenek87553c42010-01-15 20:35:54 +000051using namespace clang::cxcursor;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +000052using namespace clang::cxstring;
Steve Naroffa1c72842009-08-28 15:28:48 +000053
Ted Kremenek91554282010-11-16 08:15:36 +000054static CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) {
55 if (!TU)
56 return 0;
57 CXTranslationUnit D = new CXTranslationUnitImpl();
58 D->TUData = TU;
59 D->StringPool = createCXStringPool();
60 return D;
61}
62
Douglas Gregor562c1f92010-01-22 19:49:59 +000063/// \brief The result of comparing two source ranges.
64enum RangeComparisonResult {
65 /// \brief Either the ranges overlap or one of the ranges is invalid.
66 RangeOverlap,
Ted Kremenekf441baf2010-02-17 00:41:40 +000067
Douglas Gregor562c1f92010-01-22 19:49:59 +000068 /// \brief The first range ends before the second range starts.
69 RangeBefore,
Ted Kremenekf441baf2010-02-17 00:41:40 +000070
Douglas Gregor562c1f92010-01-22 19:49:59 +000071 /// \brief The first range starts after the second range ends.
72 RangeAfter
73};
74
Ted Kremenekf441baf2010-02-17 00:41:40 +000075/// \brief Compare two source ranges to determine their relative position in
Douglas Gregor562c1f92010-01-22 19:49:59 +000076/// the translation unit.
Ted Kremenekf441baf2010-02-17 00:41:40 +000077static RangeComparisonResult RangeCompare(SourceManager &SM,
78 SourceRange R1,
Douglas Gregor562c1f92010-01-22 19:49:59 +000079 SourceRange R2) {
80 assert(R1.isValid() && "First range is invalid?");
81 assert(R2.isValid() && "Second range is invalid?");
Douglas Gregorcd8bdd02010-07-22 20:22:31 +000082 if (R1.getEnd() != R2.getBegin() &&
Daniel Dunbar02968e52010-02-14 10:02:57 +000083 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
Douglas Gregor562c1f92010-01-22 19:49:59 +000084 return RangeBefore;
Douglas Gregorcd8bdd02010-07-22 20:22:31 +000085 if (R2.getEnd() != R1.getBegin() &&
Daniel Dunbar02968e52010-02-14 10:02:57 +000086 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
Douglas Gregor562c1f92010-01-22 19:49:59 +000087 return RangeAfter;
88 return RangeOverlap;
89}
90
Ted Kremenek680fe512010-05-05 00:55:23 +000091/// \brief Determine if a source location falls within, before, or after a
92/// a given source range.
93static RangeComparisonResult LocationCompare(SourceManager &SM,
94 SourceLocation L, SourceRange R) {
95 assert(R.isValid() && "First range is invalid?");
96 assert(L.isValid() && "Second range is invalid?");
Douglas Gregorcd8bdd02010-07-22 20:22:31 +000097 if (L == R.getBegin() || L == R.getEnd())
Ted Kremenek680fe512010-05-05 00:55:23 +000098 return RangeOverlap;
Ted Kremenek680fe512010-05-05 00:55:23 +000099 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
100 return RangeBefore;
101 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
102 return RangeAfter;
103 return RangeOverlap;
104}
105
Daniel Dunbar474b2072010-02-14 01:47:29 +0000106/// \brief Translate a Clang source range into a CIndex source range.
107///
108/// Clang internally represents ranges where the end location points to the
109/// start of the token at the end. However, for external clients it is more
110/// useful to have a CXSourceRange be a proper half-open interval. This routine
111/// does the appropriate translation.
Ted Kremenekf441baf2010-02-17 00:41:40 +0000112CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
Daniel Dunbar474b2072010-02-14 01:47:29 +0000113 const LangOptions &LangOpts,
Chris Lattnered8b6b72010-06-18 22:45:06 +0000114 const CharSourceRange &R) {
Daniel Dunbar474b2072010-02-14 01:47:29 +0000115 // We want the last character in this location, so we will adjust the
Douglas Gregoraae92242010-03-19 21:51:54 +0000116 // location accordingly.
Daniel Dunbar474b2072010-02-14 01:47:29 +0000117 SourceLocation EndLoc = R.getEnd();
Douglas Gregor229bebd2010-11-09 06:24:54 +0000118 if (EndLoc.isValid() && EndLoc.isMacroID())
119 EndLoc = SM.getSpellingLoc(EndLoc);
Chris Lattnered8b6b72010-06-18 22:45:06 +0000120 if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
Douglas Gregoraae92242010-03-19 21:51:54 +0000121 unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
Daniel Dunbar474b2072010-02-14 01:47:29 +0000122 EndLoc = EndLoc.getFileLocWithOffset(Length);
123 }
124
125 CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
126 R.getBegin().getRawEncoding(),
127 EndLoc.getRawEncoding() };
128 return Result;
129}
Douglas Gregor4f46e782010-01-19 21:36:55 +0000130
Ted Kremenek991eb3f2010-01-06 03:42:32 +0000131//===----------------------------------------------------------------------===//
Douglas Gregor562c1f92010-01-22 19:49:59 +0000132// Cursor visitor.
Ted Kremenek991eb3f2010-01-06 03:42:32 +0000133//===----------------------------------------------------------------------===//
134
Steve Naroff1054e602009-08-31 00:59:03 +0000135namespace {
Ted Kremenek92209a42010-11-11 08:05:18 +0000136
137class VisitorJob {
138public:
Ted Kremeneke12bcf52010-11-12 21:34:12 +0000139 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
Ted Kremenek573411b2010-11-13 00:58:18 +0000140 TypeLocVisitKind, OverloadExprPartsKind,
Ted Kremenek8eaa1652010-11-17 00:50:47 +0000141 DeclRefExprPartsKind, LabelRefVisitKind,
Ted Kremenek83900272010-11-18 00:02:32 +0000142 ExplicitTemplateArgsVisitKind,
143 NestedNameSpecifierVisitKind,
Douglas Gregora6ce6082011-02-25 18:19:59 +0000144 NestedNameSpecifierLocVisitKind,
Ted Kremenek5d304a32010-11-18 00:42:18 +0000145 DeclarationNameInfoVisitKind,
Douglas Gregor557f05c2011-01-19 20:34:17 +0000146 MemberRefVisitKind, SizeOfPackExprPartsKind };
Ted Kremenek92209a42010-11-11 08:05:18 +0000147protected:
Ted Kremenek83900272010-11-18 00:02:32 +0000148 void *data[3];
Ted Kremenek92209a42010-11-11 08:05:18 +0000149 CXCursor parent;
150 Kind K;
Ted Kremenek83900272010-11-18 00:02:32 +0000151 VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
152 : parent(C), K(k) {
153 data[0] = d1;
154 data[1] = d2;
155 data[2] = d3;
156 }
Ted Kremenek92209a42010-11-11 08:05:18 +0000157public:
158 Kind getKind() const { return K; }
159 const CXCursor &getParent() const { return parent; }
160 static bool classof(VisitorJob *VJ) { return true; }
161};
162
163typedef llvm::SmallVector<VisitorJob, 10> VisitorWorkList;
164
Douglas Gregor71f3d942010-01-20 20:59:29 +0000165// Cursor visitor.
Douglas Gregor93f89952010-01-21 16:28:34 +0000166class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
Ted Kremenek5d304a32010-11-18 00:42:18 +0000167 public TypeLocVisitor<CursorVisitor, bool>
Douglas Gregor93f89952010-01-21 16:28:34 +0000168{
Douglas Gregor562c1f92010-01-22 19:49:59 +0000169 /// \brief The translation unit we are traversing.
Ted Kremenek91554282010-11-16 08:15:36 +0000170 CXTranslationUnit TU;
171 ASTUnit *AU;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000172
Douglas Gregor562c1f92010-01-22 19:49:59 +0000173 /// \brief The parent cursor whose children we are traversing.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000174 CXCursor Parent;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000175
Douglas Gregor562c1f92010-01-22 19:49:59 +0000176 /// \brief The declaration that serves at the parent of any statement or
177 /// expression nodes.
Douglas Gregord1824312010-01-21 17:29:07 +0000178 Decl *StmtParent;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000179
Douglas Gregor562c1f92010-01-22 19:49:59 +0000180 /// \brief The visitor function.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000181 CXCursorVisitor Visitor;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000182
Douglas Gregor562c1f92010-01-22 19:49:59 +0000183 /// \brief The opaque client data, to be passed along to the visitor.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000184 CXClientData ClientData;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000185
Douglas Gregor16bef852009-10-16 20:01:17 +0000186 // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
187 // to the visitor. Declarations with a PCH level greater than this value will
188 // be suppressed.
189 unsigned MaxPCHLevel;
Douglas Gregor562c1f92010-01-22 19:49:59 +0000190
Douglas Gregorc2b97992011-03-16 23:23:30 +0000191 /// \brief Whether we should visit the preprocessing record entries last,
192 /// after visiting other declarations.
193 bool VisitPreprocessorLast;
194
Douglas Gregor562c1f92010-01-22 19:49:59 +0000195 /// \brief When valid, a source range to which the cursor should restrict
196 /// its search.
197 SourceRange RegionOfInterest;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000198
Ted Kremenekd40a4392010-11-02 23:10:24 +0000199 // FIXME: Eventually remove. This part of a hack to support proper
200 // iteration over all Decls contained lexically within an ObjC container.
201 DeclContext::decl_iterator *DI_current;
202 DeclContext::decl_iterator DE_current;
203
Ted Kremeneka4c27ec2010-11-15 23:31:32 +0000204 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
205 llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
206 llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
207
Douglas Gregor71f3d942010-01-20 20:59:29 +0000208 using DeclVisitor<CursorVisitor, bool>::Visit;
Douglas Gregor93f89952010-01-21 16:28:34 +0000209 using TypeLocVisitor<CursorVisitor, bool>::Visit;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000210
211 /// \brief Determine whether this particular source range comes before, comes
212 /// after, or overlaps the region of interest.
Douglas Gregor562c1f92010-01-22 19:49:59 +0000213 ///
Daniel Dunbar02968e52010-02-14 10:02:57 +0000214 /// \param R a half-open source range retrieved from the abstract syntax tree.
Ted Kremenekf441baf2010-02-17 00:41:40 +0000215 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
216
Ted Kremenek12e0f292010-05-13 00:25:00 +0000217 class SetParentRAII {
218 CXCursor &Parent;
219 Decl *&StmtParent;
220 CXCursor OldParent;
221
222 public:
223 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
224 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
225 {
226 Parent = NewParent;
227 if (clang_isDeclaration(Parent.kind))
228 StmtParent = getCursorDecl(Parent);
229 }
230
231 ~SetParentRAII() {
232 Parent = OldParent;
233 if (clang_isDeclaration(Parent.kind))
234 StmtParent = getCursorDecl(Parent);
235 }
236 };
237
Steve Naroff1054e602009-08-31 00:59:03 +0000238public:
Ted Kremenek91554282010-11-16 08:15:36 +0000239 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
240 CXClientData ClientData,
Ted Kremenekf441baf2010-02-17 00:41:40 +0000241 unsigned MaxPCHLevel,
Douglas Gregorc2b97992011-03-16 23:23:30 +0000242 bool VisitPreprocessorLast,
Douglas Gregor562c1f92010-01-22 19:49:59 +0000243 SourceRange RegionOfInterest = SourceRange())
Ted Kremenek91554282010-11-16 08:15:36 +0000244 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
245 Visitor(Visitor), ClientData(ClientData),
Douglas Gregorc2b97992011-03-16 23:23:30 +0000246 MaxPCHLevel(MaxPCHLevel), VisitPreprocessorLast(VisitPreprocessorLast),
247 RegionOfInterest(RegionOfInterest), DI_current(0)
Douglas Gregor71f3d942010-01-20 20:59:29 +0000248 {
249 Parent.kind = CXCursor_NoDeclFound;
250 Parent.data[0] = 0;
251 Parent.data[1] = 0;
252 Parent.data[2] = 0;
Douglas Gregord1824312010-01-21 17:29:07 +0000253 StmtParent = 0;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000254 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000255
Ted Kremeneka4c27ec2010-11-15 23:31:32 +0000256 ~CursorVisitor() {
257 // Free the pre-allocated worklists for data-recursion.
258 for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
259 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
260 delete *I;
261 }
262 }
263
Ted Kremenek91554282010-11-16 08:15:36 +0000264 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
265 CXTranslationUnit getTU() const { return TU; }
Ted Kremenekc7a5bae2010-11-11 08:05:23 +0000266
Douglas Gregor562c1f92010-01-22 19:49:59 +0000267 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000268
269 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
270 getPreprocessedEntities();
271
Douglas Gregor71f3d942010-01-20 20:59:29 +0000272 bool VisitChildren(CXCursor Parent);
Ted Kremenekf441baf2010-02-17 00:41:40 +0000273
Douglas Gregor93f89952010-01-21 16:28:34 +0000274 // Declaration visitors
Ted Kremenek6ab9aa022010-02-18 05:46:33 +0000275 bool VisitAttributes(Decl *D);
Ted Kremenek33b9a422010-04-11 21:47:37 +0000276 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenekae9e2212010-08-27 21:34:58 +0000277 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd40a4392010-11-02 23:10:24 +0000278 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregor71f3d942010-01-20 20:59:29 +0000279 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek7dff4162010-02-18 18:47:08 +0000280 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
281 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000282 bool VisitTagDecl(TagDecl *D);
Douglas Gregor9dc243c2010-09-01 17:32:36 +0000283 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregorf96abb22010-08-31 19:31:58 +0000284 bool VisitClassTemplatePartialSpecializationDecl(
285 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregor713602b2010-08-31 17:01:39 +0000286 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000287 bool VisitEnumConstantDecl(EnumConstantDecl *D);
288 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
289 bool VisitFunctionDecl(FunctionDecl *ND);
290 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek7dff4162010-02-18 18:47:08 +0000291 bool VisitVarDecl(VarDecl *);
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000292 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregor713602b2010-08-31 17:01:39 +0000293 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor1fbaeb12010-08-31 19:02:00 +0000294 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000295 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000296 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
297 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
298 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
299 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek49be9e02010-05-18 21:09:07 +0000300 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremeneke2110252010-02-18 22:36:18 +0000301 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
302 bool VisitObjCImplDecl(ObjCImplDecl *D);
303 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
304 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000305 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
306 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
307 bool VisitObjCClassDecl(ObjCClassDecl *D);
Douglas Gregorb1b71e52010-11-17 01:03:52 +0000308 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
Ted Kremenekb80cba52010-05-07 01:04:29 +0000309 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenekbd67fb22010-05-06 23:38:21 +0000310 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregora89314e2010-08-31 23:48:11 +0000311 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor01a430132010-09-01 03:07:18 +0000312 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregora9aa29c2010-09-01 19:52:22 +0000313 bool VisitUsingDecl(UsingDecl *D);
314 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
315 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor01a430132010-09-01 03:07:18 +0000316
Douglas Gregor12bca222010-08-31 14:41:23 +0000317 // Name visitor
318 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregor3335f482010-09-02 17:35:32 +0000319 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregora9d87bc2011-02-25 00:36:19 +0000320 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
Douglas Gregor12bca222010-08-31 14:41:23 +0000321
Douglas Gregor713602b2010-08-31 17:01:39 +0000322 // Template visitors
323 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregora23e8f72010-08-31 20:37:03 +0000324 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregor713602b2010-08-31 17:01:39 +0000325 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
326
Douglas Gregor93f89952010-01-21 16:28:34 +0000327 // Type visitors
Douglas Gregor12bca222010-08-31 14:41:23 +0000328 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000329 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor93f89952010-01-21 16:28:34 +0000330 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000331 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
332 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregor713602b2010-08-31 17:01:39 +0000333 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000334 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCall8b07ec22010-05-15 11:32:37 +0000335 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000336 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
Abramo Bagnara924a8f32010-12-10 16:29:40 +0000337 bool VisitParenTypeLoc(ParenTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000338 bool VisitPointerTypeLoc(PointerTypeLoc TL);
339 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
340 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
341 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
342 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor12bca222010-08-31 14:41:23 +0000343 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregord1824312010-01-21 17:29:07 +0000344 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregor713602b2010-08-31 17:01:39 +0000345 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor6479fc42010-01-21 20:48:56 +0000346 // FIXME: Implement visitors here when the unimplemented TypeLocs get
347 // implemented
348 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
Douglas Gregord2fa7662010-12-20 02:24:11 +0000349 bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
Douglas Gregor6479fc42010-01-21 20:48:56 +0000350 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Douglas Gregor3d0da5f2011-03-01 01:34:45 +0000351 bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
Douglas Gregora7a795b2011-03-01 20:11:18 +0000352 bool VisitDependentTemplateSpecializationTypeLoc(
353 DependentTemplateSpecializationTypeLoc TL);
Douglas Gregor844cb502011-03-01 18:12:44 +0000354 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
Douglas Gregor3d0da5f2011-03-01 01:34:45 +0000355
Ted Kremenek92209a42010-11-11 08:05:18 +0000356 // Data-recursive visitor functions.
357 bool IsInRegionOfInterest(CXCursor C);
358 bool RunVisitorWorkList(VisitorWorkList &WL);
359 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
Ted Kremenek5d304a32010-11-18 00:42:18 +0000360 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
Steve Naroff1054e602009-08-31 00:59:03 +0000361};
Ted Kremenekf441baf2010-02-17 00:41:40 +0000362
Ted Kremenek0ec2cca2010-01-05 19:32:54 +0000363} // end anonymous namespace
Benjamin Kramer61f5d0c2009-10-18 16:11:04 +0000364
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000365static SourceRange getRawCursorExtent(CXCursor C);
Douglas Gregor29ee4222010-11-17 17:14:07 +0000366static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
367
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000368
Douglas Gregor562c1f92010-01-22 19:49:59 +0000369RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Ted Kremenek91554282010-11-16 08:15:36 +0000370 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
Douglas Gregor562c1f92010-01-22 19:49:59 +0000371}
372
Douglas Gregor71f3d942010-01-20 20:59:29 +0000373/// \brief Visit the given cursor and, if requested by the visitor,
374/// its children.
375///
Douglas Gregor562c1f92010-01-22 19:49:59 +0000376/// \param Cursor the cursor to visit.
377///
378/// \param CheckRegionOfInterest if true, then the caller already checked that
379/// this cursor is within the region of interest.
380///
Douglas Gregor71f3d942010-01-20 20:59:29 +0000381/// \returns true if the visitation should be aborted, false if it
382/// should continue.
Douglas Gregor562c1f92010-01-22 19:49:59 +0000383bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregor71f3d942010-01-20 20:59:29 +0000384 if (clang_isInvalid(Cursor.kind))
385 return false;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000386
Douglas Gregor71f3d942010-01-20 20:59:29 +0000387 if (clang_isDeclaration(Cursor.kind)) {
388 Decl *D = getCursorDecl(Cursor);
389 assert(D && "Invalid declaration cursor");
390 if (D->getPCHLevel() > MaxPCHLevel)
391 return false;
392
393 if (D->isImplicit())
394 return false;
395 }
396
Douglas Gregor562c1f92010-01-22 19:49:59 +0000397 // If we have a range of interest, and this cursor doesn't intersect with it,
398 // we're done.
399 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000400 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbar2f4ba172010-02-14 08:32:05 +0000401 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor562c1f92010-01-22 19:49:59 +0000402 return false;
403 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000404
Douglas Gregor71f3d942010-01-20 20:59:29 +0000405 switch (Visitor(Cursor, Parent, ClientData)) {
406 case CXChildVisit_Break:
407 return true;
408
409 case CXChildVisit_Continue:
410 return false;
411
412 case CXChildVisit_Recurse:
413 return VisitChildren(Cursor);
414 }
415
Douglas Gregor33f16852010-01-25 16:45:46 +0000416 return false;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000417}
418
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000419std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
420CursorVisitor::getPreprocessedEntities() {
421 PreprocessingRecord &PPRec
Ted Kremenek91554282010-11-16 08:15:36 +0000422 = *AU->getPreprocessor().getPreprocessingRecord();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000423
424 bool OnlyLocalDecls
Douglas Gregorfd4da712010-12-21 19:07:48 +0000425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls && RegionOfInterest.isValid()) {
428 // If we would only look at local declarations but we have a region of
429 // interest, check whether that region of interest is in the main file.
430 // If not, we should traverse all declarations.
431 // FIXME: My kingdom for a proper binary search approach to finding
432 // cursors!
433 std::pair<FileID, unsigned> Location
434 = AU->getSourceManager().getDecomposedInstantiationLoc(
435 RegionOfInterest.getBegin());
436 if (Location.first != AU->getSourceManager().getMainFileID())
437 OnlyLocalDecls = false;
438 }
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000439
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000440 PreprocessingRecord::iterator StartEntity, EndEntity;
441 if (OnlyLocalDecls) {
442 StartEntity = AU->pp_entity_begin();
443 EndEntity = AU->pp_entity_end();
444 } else {
445 StartEntity = PPRec.begin();
446 EndEntity = PPRec.end();
447 }
448
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000449 // There is no region of interest; we have to walk everything.
450 if (RegionOfInterest.isInvalid())
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000451 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000452
453 // Find the file in which the region of interest lands.
Ted Kremenek91554282010-11-16 08:15:36 +0000454 SourceManager &SM = AU->getSourceManager();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000455 std::pair<FileID, unsigned> Begin
456 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
457 std::pair<FileID, unsigned> End
458 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
459
460 // The region of interest spans files; we have to walk everything.
461 if (Begin.first != End.first)
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000462 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000463
464 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
Ted Kremenek91554282010-11-16 08:15:36 +0000465 = AU->getPreprocessedEntitiesByFile();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000466 if (ByFileMap.empty()) {
467 // Build the mapping from files to sets of preprocessed entities.
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000468 for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000469 std::pair<FileID, unsigned> P
470 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000471
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000472 ByFileMap[P.first].push_back(*E);
473 }
474 }
475
476 return std::make_pair(ByFileMap[Begin.first].begin(),
477 ByFileMap[Begin.first].end());
478}
479
Douglas Gregor71f3d942010-01-20 20:59:29 +0000480/// \brief Visit the children of the given cursor.
Ted Kremenek91554282010-11-16 08:15:36 +0000481///
Douglas Gregor71f3d942010-01-20 20:59:29 +0000482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
Ted Kremenekf441baf2010-02-17 00:41:40 +0000484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregor64f38ae2011-03-02 19:17:03 +0000485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000487 // By definition, references have no children.
488 return false;
489 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000490
491 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregor71f3d942010-01-20 20:59:29 +0000492 // done.
Ted Kremenek12e0f292010-05-13 00:25:00 +0000493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf441baf2010-02-17 00:41:40 +0000494
Douglas Gregor71f3d942010-01-20 20:59:29 +0000495 if (clang_isDeclaration(Cursor.kind)) {
496 Decl *D = getCursorDecl(Cursor);
Douglas Gregor7df21262011-04-14 21:41:34 +0000497 if (!D)
498 return false;
499
Ted Kremenek0e293092010-02-18 18:47:01 +0000500 return VisitAttributes(D) || Visit(D);
Douglas Gregor71f3d942010-01-20 20:59:29 +0000501 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000502
Douglas Gregor7df21262011-04-14 21:41:34 +0000503 if (clang_isStatement(Cursor.kind)) {
504 if (Stmt *S = getCursorStmt(Cursor))
505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
511 if (Expr *E = getCursorExpr(Cursor))
512 return Visit(E);
513
514 return false;
515 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000516
Douglas Gregor71f3d942010-01-20 20:59:29 +0000517 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremenek91554282010-11-16 08:15:36 +0000518 CXTranslationUnit tu = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregorc2b97992011-03-16 23:23:30 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
529 if (Visit(MakeCXCursor(*TL, tu), true))
530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000534 return true;
Douglas Gregorc2b97992011-03-16 23:23:30 +0000535 continue;
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000536 }
Bob Wilson4f559a32010-03-19 03:57:57 +0000537
Douglas Gregorc2b97992011-03-16 23:23:30 +0000538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
540 // FIXME: Once we have the ability to deserialize a preprocessing record,
541 // do so.
542 PreprocessingRecord::iterator E, EEnd;
543 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
544 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
545 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
546 return true;
547
548 continue;
549 }
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000550
Douglas Gregorc2b97992011-03-16 23:23:30 +0000551 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
552 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
553 return true;
554
555 continue;
556 }
Douglas Gregor5272e802010-03-19 05:22:59 +0000557
Douglas Gregorc2b97992011-03-16 23:23:30 +0000558 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
559 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
560 return true;
561
562 continue;
563 }
Douglas Gregor796d76a2010-10-20 22:00:55 +0000564 }
Douglas Gregor5272e802010-03-19 05:22:59 +0000565 }
566 }
Douglas Gregorc2b97992011-03-16 23:23:30 +0000567
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000568 return false;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000569 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000570
Douglas Gregor64f38ae2011-03-02 19:17:03 +0000571 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
572 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
573 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
574 return Visit(BaseTSInfo->getTypeLoc());
575 }
576 }
577 }
578
Douglas Gregor71f3d942010-01-20 20:59:29 +0000579 // Nothing to visit at the moment.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000580 return false;
581}
582
Ted Kremenek33b9a422010-04-11 21:47:37 +0000583bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
John McCalla3cecb62010-06-04 22:33:30 +0000584 if (Visit(B->getSignatureAsWritten()->getTypeLoc()))
585 return true;
Ted Kremenek33b9a422010-04-11 21:47:37 +0000586
Ted Kremenek60fe71a2010-07-22 11:30:19 +0000587 if (Stmt *Body = B->getBody())
588 return Visit(MakeCXCursor(Body, StmtParent, TU));
589
590 return false;
Ted Kremenek33b9a422010-04-11 21:47:37 +0000591}
592
Ted Kremenekd40a4392010-11-02 23:10:24 +0000593llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
594 if (RegionOfInterest.isValid()) {
Douglas Gregor29ee4222010-11-17 17:14:07 +0000595 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd40a4392010-11-02 23:10:24 +0000596 if (Range.isInvalid())
597 return llvm::Optional<bool>();
Douglas Gregor29ee4222010-11-17 17:14:07 +0000598
Ted Kremenekd40a4392010-11-02 23:10:24 +0000599 switch (CompareRegionOfInterest(Range)) {
600 case RangeBefore:
601 // This declaration comes before the region of interest; skip it.
602 return llvm::Optional<bool>();
603
604 case RangeAfter:
605 // This declaration comes after the region of interest; we're done.
606 return false;
607
608 case RangeOverlap:
609 // This declaration overlaps the region of interest; visit it.
610 break;
611 }
612 }
613 return true;
614}
615
616bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
617 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
618
619 // FIXME: Eventually remove. This part of a hack to support proper
620 // iteration over all Decls contained lexically within an ObjC container.
621 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
622 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
623
624 for ( ; I != E; ++I) {
Ted Kremenek49be9e02010-05-18 21:09:07 +0000625 Decl *D = *I;
626 if (D->getLexicalDeclContext() != DC)
627 continue;
Ted Kremenek49be9e02010-05-18 21:09:07 +0000628 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd40a4392010-11-02 23:10:24 +0000629 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
630 if (!V.hasValue())
631 continue;
632 if (!V.getValue())
633 return false;
Daniel Dunbar02968e52010-02-14 10:02:57 +0000634 if (Visit(Cursor, true))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000635 return true;
636 }
Douglas Gregor71f3d942010-01-20 20:59:29 +0000637 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +0000638}
639
Douglas Gregord824f882010-01-22 00:50:27 +0000640bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
641 llvm_unreachable("Translation units are visited directly by Visit()");
642 return false;
643}
644
645bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
646 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
647 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf441baf2010-02-17 00:41:40 +0000648
Douglas Gregord824f882010-01-22 00:50:27 +0000649 return false;
650}
651
652bool CursorVisitor::VisitTagDecl(TagDecl *D) {
653 return VisitDeclContext(D);
654}
655
Douglas Gregor9dc243c2010-09-01 17:32:36 +0000656bool CursorVisitor::VisitClassTemplateSpecializationDecl(
657 ClassTemplateSpecializationDecl *D) {
658 bool ShouldVisitBody = false;
659 switch (D->getSpecializationKind()) {
660 case TSK_Undeclared:
661 case TSK_ImplicitInstantiation:
662 // Nothing to visit
663 return false;
664
665 case TSK_ExplicitInstantiationDeclaration:
666 case TSK_ExplicitInstantiationDefinition:
667 break;
668
669 case TSK_ExplicitSpecialization:
670 ShouldVisitBody = true;
671 break;
672 }
673
674 // Visit the template arguments used in the specialization.
675 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
676 TypeLoc TL = SpecType->getTypeLoc();
677 if (TemplateSpecializationTypeLoc *TSTLoc
678 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
679 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
680 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
681 return true;
682 }
683 }
684
685 if (ShouldVisitBody && VisitCXXRecordDecl(D))
686 return true;
687
688 return false;
689}
690
Douglas Gregorf96abb22010-08-31 19:31:58 +0000691bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
692 ClassTemplatePartialSpecializationDecl *D) {
693 // FIXME: Visit the "outer" template parameter lists on the TagDecl
694 // before visiting these template parameters.
695 if (VisitTemplateParameters(D->getTemplateParameters()))
696 return true;
697
698 // Visit the partial specialization arguments.
699 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
700 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
702 return true;
703
704 return VisitCXXRecordDecl(D);
705}
706
Douglas Gregor713602b2010-08-31 17:01:39 +0000707bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000708 // Visit the default argument.
709 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
710 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
711 if (Visit(DefArg->getTypeLoc()))
712 return true;
713
Douglas Gregor713602b2010-08-31 17:01:39 +0000714 return false;
715}
716
Douglas Gregord824f882010-01-22 00:50:27 +0000717bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
718 if (Expr *Init = D->getInitExpr())
719 return Visit(MakeCXCursor(Init, StmtParent, TU));
720 return false;
721}
722
Douglas Gregor93f89952010-01-21 16:28:34 +0000723bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
724 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
725 if (Visit(TSInfo->getTypeLoc()))
726 return true;
727
Douglas Gregor14454802011-02-25 02:25:35 +0000728 // Visit the nested-name-specifier, if present.
729 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
730 if (VisitNestedNameSpecifierLoc(QualifierLoc))
731 return true;
732
Douglas Gregor93f89952010-01-21 16:28:34 +0000733 return false;
734}
735
Douglas Gregorf3af3112010-09-09 21:42:20 +0000736/// \brief Compare two base or member initializers based on their source order.
Alexis Hunt1d792652011-01-08 20:30:50 +0000737static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
738 CXXCtorInitializer const * const *X
739 = static_cast<CXXCtorInitializer const * const *>(Xp);
740 CXXCtorInitializer const * const *Y
741 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregorf3af3112010-09-09 21:42:20 +0000742
743 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
744 return -1;
745 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
746 return 1;
747 else
748 return 0;
749}
750
Douglas Gregor71f3d942010-01-20 20:59:29 +0000751bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor12bca222010-08-31 14:41:23 +0000752 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
753 // Visit the function declaration's syntactic components in the order
754 // written. This requires a bit of work.
Abramo Bagnara6d810632010-12-14 22:11:44 +0000755 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor12bca222010-08-31 14:41:23 +0000756 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
757
758 // If we have a function declared directly (without the use of a typedef),
759 // visit just the return type. Otherwise, just visit the function's type
760 // now.
761 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
762 (!FTL && Visit(TL)))
763 return true;
764
Douglas Gregor3335f482010-09-02 17:35:32 +0000765 // Visit the nested-name-specifier, if present.
Douglas Gregor14454802011-02-25 02:25:35 +0000766 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +0000768 return true;
Douglas Gregor12bca222010-08-31 14:41:23 +0000769
770 // Visit the declaration name.
771 if (VisitDeclarationNameInfo(ND->getNameInfo()))
772 return true;
773
774 // FIXME: Visit explicitly-specified template arguments!
775
776 // Visit the function parameters, if we have a function type.
777 if (FTL && VisitFunctionTypeLoc(*FTL, true))
778 return true;
779
780 // FIXME: Attributes?
781 }
782
Douglas Gregorf3af3112010-09-09 21:42:20 +0000783 if (ND->isThisDeclarationADefinition()) {
784 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
785 // Find the initializers that were written in the source.
Alexis Hunt1d792652011-01-08 20:30:50 +0000786 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregorf3af3112010-09-09 21:42:20 +0000787 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
788 IEnd = Constructor->init_end();
789 I != IEnd; ++I) {
790 if (!(*I)->isWritten())
791 continue;
792
793 WrittenInits.push_back(*I);
794 }
795
796 // Sort the initializers in source order
797 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Alexis Hunt1d792652011-01-08 20:30:50 +0000798 &CompareCXXCtorInitializers);
Douglas Gregorf3af3112010-09-09 21:42:20 +0000799
800 // Visit the initializers in source order
801 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Alexis Hunt1d792652011-01-08 20:30:50 +0000802 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichetd583da02010-12-04 09:14:42 +0000803 if (Init->isAnyMemberInitializer()) {
804 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregorf3af3112010-09-09 21:42:20 +0000805 Init->getMemberLocation(), TU)))
806 return true;
807 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
808 if (Visit(BaseInfo->getTypeLoc()))
809 return true;
810 }
811
812 // Visit the initializer value.
813 if (Expr *Initializer = Init->getInit())
814 if (Visit(MakeCXCursor(Initializer, ND, TU)))
815 return true;
816 }
817 }
818
819 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
820 return true;
821 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000822
Douglas Gregor71f3d942010-01-20 20:59:29 +0000823 return false;
824}
Ted Kremenek78668fd2010-01-13 00:22:49 +0000825
Douglas Gregord824f882010-01-22 00:50:27 +0000826bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
827 if (VisitDeclaratorDecl(D))
828 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000829
Douglas Gregord824f882010-01-22 00:50:27 +0000830 if (Expr *BitWidth = D->getBitWidth())
831 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf441baf2010-02-17 00:41:40 +0000832
Douglas Gregord824f882010-01-22 00:50:27 +0000833 return false;
834}
835
836bool CursorVisitor::VisitVarDecl(VarDecl *D) {
837 if (VisitDeclaratorDecl(D))
838 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000839
Douglas Gregord824f882010-01-22 00:50:27 +0000840 if (Expr *Init = D->getInit())
841 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf441baf2010-02-17 00:41:40 +0000842
Douglas Gregord824f882010-01-22 00:50:27 +0000843 return false;
844}
845
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000846bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
847 if (VisitDeclaratorDecl(D))
848 return true;
849
850 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
851 if (Expr *DefArg = D->getDefaultArgument())
852 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
853
854 return false;
855}
856
Douglas Gregor713602b2010-08-31 17:01:39 +0000857bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
858 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
859 // before visiting these template parameters.
860 if (VisitTemplateParameters(D->getTemplateParameters()))
861 return true;
862
863 return VisitFunctionDecl(D->getTemplatedDecl());
864}
865
Douglas Gregor1fbaeb12010-08-31 19:02:00 +0000866bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
867 // FIXME: Visit the "outer" template parameter lists on the TagDecl
868 // before visiting these template parameters.
869 if (VisitTemplateParameters(D->getTemplateParameters()))
870 return true;
871
872 return VisitCXXRecordDecl(D->getTemplatedDecl());
873}
874
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000875bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
876 if (VisitTemplateParameters(D->getTemplateParameters()))
877 return true;
878
879 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
880 VisitTemplateArgumentLoc(D->getDefaultArgument()))
881 return true;
882
883 return false;
884}
885
Douglas Gregord824f882010-01-22 00:50:27 +0000886bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor12852d92010-03-08 14:59:44 +0000887 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
888 if (Visit(TSInfo->getTypeLoc()))
889 return true;
890
Ted Kremenekf441baf2010-02-17 00:41:40 +0000891 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregord824f882010-01-22 00:50:27 +0000892 PEnd = ND->param_end();
893 P != PEnd; ++P) {
894 if (Visit(MakeCXCursor(*P, TU)))
895 return true;
896 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000897
Douglas Gregord824f882010-01-22 00:50:27 +0000898 if (ND->isThisDeclarationADefinition() &&
899 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
900 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000901
Douglas Gregord824f882010-01-22 00:50:27 +0000902 return false;
903}
904
Ted Kremenekd40a4392010-11-02 23:10:24 +0000905namespace {
906 struct ContainerDeclsSort {
907 SourceManager &SM;
908 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
909 bool operator()(Decl *A, Decl *B) {
910 SourceLocation L_A = A->getLocStart();
911 SourceLocation L_B = B->getLocStart();
912 assert(L_A.isValid() && L_B.isValid());
913 return SM.isBeforeInTranslationUnit(L_A, L_B);
914 }
915 };
916}
917
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000918bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd40a4392010-11-02 23:10:24 +0000919 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
920 // an @implementation can lexically contain Decls that are not properly
921 // nested in the AST. When we identify such cases, we need to retrofit
922 // this nesting here.
923 if (!DI_current)
924 return VisitDeclContext(D);
925
926 // Scan the Decls that immediately come after the container
927 // in the current DeclContext. If any fall within the
928 // container's lexical region, stash them into a vector
929 // for later processing.
930 llvm::SmallVector<Decl *, 24> DeclsInContainer;
931 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremenek91554282010-11-16 08:15:36 +0000932 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd40a4392010-11-02 23:10:24 +0000933 if (EndLoc.isValid()) {
934 DeclContext::decl_iterator next = *DI_current;
935 while (++next != DE_current) {
936 Decl *D_next = *next;
937 if (!D_next)
938 break;
939 SourceLocation L = D_next->getLocStart();
940 if (!L.isValid())
941 break;
942 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
943 *DI_current = next;
944 DeclsInContainer.push_back(D_next);
945 continue;
946 }
947 break;
948 }
949 }
950
951 // The common case.
952 if (DeclsInContainer.empty())
953 return VisitDeclContext(D);
954
955 // Get all the Decls in the DeclContext, and sort them with the
956 // additional ones we've collected. Then visit them.
957 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
958 I!=E; ++I) {
959 Decl *subDecl = *I;
Ted Kremenek4bd4d752010-11-02 23:17:51 +0000960 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
961 subDecl->getLocStart().isInvalid())
Ted Kremenekd40a4392010-11-02 23:10:24 +0000962 continue;
963 DeclsInContainer.push_back(subDecl);
964 }
965
966 // Now sort the Decls so that they appear in lexical order.
967 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
968 ContainerDeclsSort(SM));
969
970 // Now visit the decls.
971 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
972 E = DeclsInContainer.end(); I != E; ++I) {
973 CXCursor Cursor = MakeCXCursor(*I, TU);
974 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
975 if (!V.hasValue())
976 continue;
977 if (!V.getValue())
978 return false;
979 if (Visit(Cursor, true))
980 return true;
981 }
982 return false;
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000983}
984
Douglas Gregor71f3d942010-01-20 20:59:29 +0000985bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorfed36b12010-01-20 23:57:43 +0000986 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
987 TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000988 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000989
Douglas Gregoref6eb842010-01-16 15:44:18 +0000990 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
991 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
992 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +0000993 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000994 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000995
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000996 return VisitObjCContainerDecl(ND);
Ted Kremenek78668fd2010-01-13 00:22:49 +0000997}
998
Douglas Gregord824f882010-01-22 00:50:27 +0000999bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1000 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1001 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1002 E = PID->protocol_end(); I != E; ++I, ++PL)
1003 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1004 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001005
Douglas Gregord824f882010-01-22 00:50:27 +00001006 return VisitObjCContainerDecl(PID);
1007}
1008
Ted Kremenek49be9e02010-05-18 21:09:07 +00001009bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor9f0e1aa2010-09-09 17:09:21 +00001010 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCalla3cecb62010-06-04 22:33:30 +00001011 return true;
1012
Ted Kremenek49be9e02010-05-18 21:09:07 +00001013 // FIXME: This implements a workaround with @property declarations also being
1014 // installed in the DeclContext for the @interface. Eventually this code
1015 // should be removed.
1016 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1017 if (!CDecl || !CDecl->IsClassExtension())
1018 return false;
1019
1020 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1021 if (!ID)
1022 return false;
1023
1024 IdentifierInfo *PropertyId = PD->getIdentifier();
1025 ObjCPropertyDecl *prevDecl =
1026 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1027
1028 if (!prevDecl)
1029 return false;
1030
1031 // Visit synthesized methods since they will be skipped when visiting
1032 // the @interface.
1033 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremenek2f075632010-09-21 20:52:59 +00001034 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek49be9e02010-05-18 21:09:07 +00001035 if (Visit(MakeCXCursor(MD, TU)))
1036 return true;
1037
1038 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremenek2f075632010-09-21 20:52:59 +00001039 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek49be9e02010-05-18 21:09:07 +00001040 if (Visit(MakeCXCursor(MD, TU)))
1041 return true;
1042
1043 return false;
1044}
1045
Douglas Gregor71f3d942010-01-20 20:59:29 +00001046bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenek78668fd2010-01-13 00:22:49 +00001047 // Issue callbacks for super class.
Douglas Gregor71f3d942010-01-20 20:59:29 +00001048 if (D->getSuperClass() &&
1049 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf441baf2010-02-17 00:41:40 +00001050 D->getSuperClassLoc(),
Douglas Gregorfed36b12010-01-20 23:57:43 +00001051 TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001052 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001053
Douglas Gregoref6eb842010-01-16 15:44:18 +00001054 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1055 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1056 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +00001057 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001058 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001059
Douglas Gregor5e8cf372010-01-21 23:27:09 +00001060 return VisitObjCContainerDecl(D);
Ted Kremenek78668fd2010-01-13 00:22:49 +00001061}
1062
Douglas Gregord824f882010-01-22 00:50:27 +00001063bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1064 return VisitObjCContainerDecl(D);
Ted Kremenek78668fd2010-01-13 00:22:49 +00001065}
1066
Douglas Gregord824f882010-01-22 00:50:27 +00001067bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremeneke184ac52010-03-19 20:39:03 +00001068 // 'ID' could be null when dealing with invalid code.
1069 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1070 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1071 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001072
Douglas Gregord824f882010-01-22 00:50:27 +00001073 return VisitObjCImplDecl(D);
1074}
1075
1076bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1077#if 0
1078 // Issue callbacks for super class.
1079 // FIXME: No source location information!
1080 if (D->getSuperClass() &&
1081 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf441baf2010-02-17 00:41:40 +00001082 D->getSuperClassLoc(),
Douglas Gregord824f882010-01-22 00:50:27 +00001083 TU)))
1084 return true;
1085#endif
Ted Kremenekf441baf2010-02-17 00:41:40 +00001086
Douglas Gregord824f882010-01-22 00:50:27 +00001087 return VisitObjCImplDecl(D);
1088}
1089
1090bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1091 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1092 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1093 E = D->protocol_end();
1094 I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +00001095 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001096 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001097
1098 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +00001099}
1100
Douglas Gregord824f882010-01-22 00:50:27 +00001101bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1102 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1103 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1104 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001105
Douglas Gregord824f882010-01-22 00:50:27 +00001106 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +00001107}
1108
Douglas Gregorb1b71e52010-11-17 01:03:52 +00001109bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1110 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1111 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1112
1113 return false;
1114}
1115
Ted Kremenekbd67fb22010-05-06 23:38:21 +00001116bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1117 return VisitDeclContext(D);
1118}
1119
Douglas Gregora89314e2010-08-31 23:48:11 +00001120bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001121 // Visit nested-name-specifier.
Douglas Gregorc05ba2e2011-02-25 17:08:07 +00001122 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1123 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001124 return true;
Douglas Gregora89314e2010-08-31 23:48:11 +00001125
1126 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1127 D->getTargetNameLoc(), TU));
1128}
1129
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001130bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001131 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001132 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1133 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001134 return true;
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001135 }
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001136
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001137 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1138 return true;
1139
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001140 return VisitDeclarationNameInfo(D->getNameInfo());
1141}
1142
Douglas Gregor01a430132010-09-01 03:07:18 +00001143bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001144 // Visit nested-name-specifier.
Douglas Gregor12441b32011-02-25 16:33:46 +00001145 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1146 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001147 return true;
Douglas Gregor01a430132010-09-01 03:07:18 +00001148
1149 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1150 D->getIdentLocation(), TU));
1151}
1152
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001153bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001154 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001155 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1156 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001157 return true;
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001158 }
Douglas Gregor3335f482010-09-02 17:35:32 +00001159
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001160 return VisitDeclarationNameInfo(D->getNameInfo());
1161}
1162
1163bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1164 UnresolvedUsingTypenameDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001165 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001168 return true;
1169
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001170 return false;
1171}
1172
Douglas Gregor12bca222010-08-31 14:41:23 +00001173bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1174 switch (Name.getName().getNameKind()) {
1175 case clang::DeclarationName::Identifier:
1176 case clang::DeclarationName::CXXLiteralOperatorName:
1177 case clang::DeclarationName::CXXOperatorName:
1178 case clang::DeclarationName::CXXUsingDirective:
1179 return false;
1180
1181 case clang::DeclarationName::CXXConstructorName:
1182 case clang::DeclarationName::CXXDestructorName:
1183 case clang::DeclarationName::CXXConversionFunctionName:
1184 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1185 return Visit(TSInfo->getTypeLoc());
1186 return false;
1187
1188 case clang::DeclarationName::ObjCZeroArgSelector:
1189 case clang::DeclarationName::ObjCOneArgSelector:
1190 case clang::DeclarationName::ObjCMultiArgSelector:
1191 // FIXME: Per-identifier location info?
1192 return false;
1193 }
1194
1195 return false;
1196}
1197
Douglas Gregor3335f482010-09-02 17:35:32 +00001198bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1199 SourceRange Range) {
1200 // FIXME: This whole routine is a hack to work around the lack of proper
1201 // source information in nested-name-specifiers (PR5791). Since we do have
1202 // a beginning source location, we can visit the first component of the
1203 // nested-name-specifier, if it's a single-token component.
1204 if (!NNS)
1205 return false;
1206
1207 // Get the first component in the nested-name-specifier.
1208 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1209 NNS = Prefix;
1210
1211 switch (NNS->getKind()) {
1212 case NestedNameSpecifier::Namespace:
Douglas Gregor3335f482010-09-02 17:35:32 +00001213 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1214 TU));
1215
Douglas Gregor7b26ff92011-02-24 02:36:08 +00001216 case NestedNameSpecifier::NamespaceAlias:
1217 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1218 Range.getBegin(), TU));
1219
Douglas Gregor3335f482010-09-02 17:35:32 +00001220 case NestedNameSpecifier::TypeSpec: {
1221 // If the type has a form where we know that the beginning of the source
1222 // range matches up with a reference cursor. Visit the appropriate reference
1223 // cursor.
John McCall424cec92011-01-19 06:33:43 +00001224 const Type *T = NNS->getAsType();
Douglas Gregor3335f482010-09-02 17:35:32 +00001225 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1226 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1227 if (const TagType *Tag = dyn_cast<TagType>(T))
1228 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1229 if (const TemplateSpecializationType *TST
1230 = dyn_cast<TemplateSpecializationType>(T))
1231 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1232 break;
1233 }
1234
1235 case NestedNameSpecifier::TypeSpecWithTemplate:
1236 case NestedNameSpecifier::Global:
1237 case NestedNameSpecifier::Identifier:
1238 break;
1239 }
1240
1241 return false;
1242}
1243
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001244bool
1245CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1246 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1247 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1248 Qualifiers.push_back(Qualifier);
1249
1250 while (!Qualifiers.empty()) {
1251 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1252 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1253 switch (NNS->getKind()) {
1254 case NestedNameSpecifier::Namespace:
1255 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregor14454802011-02-25 02:25:35 +00001256 Q.getLocalBeginLoc(),
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001257 TU)))
1258 return true;
1259
1260 break;
1261
1262 case NestedNameSpecifier::NamespaceAlias:
1263 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
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::TypeSpec:
1271 case NestedNameSpecifier::TypeSpecWithTemplate:
1272 if (Visit(Q.getTypeLoc()))
1273 return true;
1274
1275 break;
1276
1277 case NestedNameSpecifier::Global:
1278 case NestedNameSpecifier::Identifier:
1279 break;
1280 }
1281 }
1282
1283 return false;
1284}
1285
Douglas Gregor713602b2010-08-31 17:01:39 +00001286bool CursorVisitor::VisitTemplateParameters(
1287 const TemplateParameterList *Params) {
1288 if (!Params)
1289 return false;
1290
1291 for (TemplateParameterList::const_iterator P = Params->begin(),
1292 PEnd = Params->end();
1293 P != PEnd; ++P) {
1294 if (Visit(MakeCXCursor(*P, TU)))
1295 return true;
1296 }
1297
1298 return false;
1299}
1300
Douglas Gregora23e8f72010-08-31 20:37:03 +00001301bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1302 switch (Name.getKind()) {
1303 case TemplateName::Template:
1304 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1305
1306 case TemplateName::OverloadedTemplate:
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001307 // Visit the overloaded template set.
1308 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1309 return true;
1310
Douglas Gregora23e8f72010-08-31 20:37:03 +00001311 return false;
1312
1313 case TemplateName::DependentTemplate:
1314 // FIXME: Visit nested-name-specifier.
1315 return false;
1316
1317 case TemplateName::QualifiedTemplate:
1318 // FIXME: Visit nested-name-specifier.
1319 return Visit(MakeCursorTemplateRef(
1320 Name.getAsQualifiedTemplateName()->getDecl(),
1321 Loc, TU));
Douglas Gregor5590be02011-01-15 06:45:20 +00001322
1323 case TemplateName::SubstTemplateTemplateParmPack:
1324 return Visit(MakeCursorTemplateRef(
1325 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1326 Loc, TU));
Douglas Gregora23e8f72010-08-31 20:37:03 +00001327 }
1328
1329 return false;
1330}
1331
Douglas Gregor713602b2010-08-31 17:01:39 +00001332bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1333 switch (TAL.getArgument().getKind()) {
1334 case TemplateArgument::Null:
1335 case TemplateArgument::Integral:
Douglas Gregor0192c232010-12-20 16:52:59 +00001336 case TemplateArgument::Pack:
Douglas Gregor713602b2010-08-31 17:01:39 +00001337 return false;
1338
Douglas Gregor713602b2010-08-31 17:01:39 +00001339 case TemplateArgument::Type:
1340 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1341 return Visit(TSInfo->getTypeLoc());
1342 return false;
1343
1344 case TemplateArgument::Declaration:
1345 if (Expr *E = TAL.getSourceDeclExpression())
1346 return Visit(MakeCXCursor(E, StmtParent, TU));
1347 return false;
1348
1349 case TemplateArgument::Expression:
1350 if (Expr *E = TAL.getSourceExpression())
1351 return Visit(MakeCXCursor(E, StmtParent, TU));
1352 return false;
1353
1354 case TemplateArgument::Template:
Douglas Gregore4ff4b52011-01-05 18:58:31 +00001355 case TemplateArgument::TemplateExpansion:
Douglas Gregor9d802122011-03-02 17:09:35 +00001356 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1357 return true;
1358
Douglas Gregore4ff4b52011-01-05 18:58:31 +00001359 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregora23e8f72010-08-31 20:37:03 +00001360 TAL.getTemplateNameLoc());
Douglas Gregor713602b2010-08-31 17:01:39 +00001361 }
1362
1363 return false;
1364}
1365
Ted Kremenekb80cba52010-05-07 01:04:29 +00001366bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1367 return VisitDeclContext(D);
1368}
1369
Douglas Gregor12bca222010-08-31 14:41:23 +00001370bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1371 return Visit(TL.getUnqualifiedLoc());
1372}
1373
Douglas Gregord1824312010-01-21 17:29:07 +00001374bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremenek91554282010-11-16 08:15:36 +00001375 ASTContext &Context = AU->getASTContext();
Douglas Gregord1824312010-01-21 17:29:07 +00001376
1377 // Some builtin types (such as Objective-C's "id", "sel", and
1378 // "Class") have associated declarations. Create cursors for those.
1379 QualType VisitType;
1380 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001381 case BuiltinType::Void:
Douglas Gregord1824312010-01-21 17:29:07 +00001382 case BuiltinType::Bool:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001383 case BuiltinType::Char_U:
1384 case BuiltinType::UChar:
Douglas Gregord1824312010-01-21 17:29:07 +00001385 case BuiltinType::Char16:
1386 case BuiltinType::Char32:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001387 case BuiltinType::UShort:
Douglas Gregord1824312010-01-21 17:29:07 +00001388 case BuiltinType::UInt:
1389 case BuiltinType::ULong:
1390 case BuiltinType::ULongLong:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001391 case BuiltinType::UInt128:
1392 case BuiltinType::Char_S:
1393 case BuiltinType::SChar:
Chris Lattnerad3467e2010-12-25 23:25:43 +00001394 case BuiltinType::WChar_U:
1395 case BuiltinType::WChar_S:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001396 case BuiltinType::Short:
1397 case BuiltinType::Int:
1398 case BuiltinType::Long:
1399 case BuiltinType::LongLong:
1400 case BuiltinType::Int128:
1401 case BuiltinType::Float:
1402 case BuiltinType::Double:
1403 case BuiltinType::LongDouble:
1404 case BuiltinType::NullPtr:
1405 case BuiltinType::Overload:
1406 case BuiltinType::Dependent:
John McCall31996342011-04-07 08:22:57 +00001407 case BuiltinType::UnknownAny:
Douglas Gregord1824312010-01-21 17:29:07 +00001408 break;
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001409
Ted Kremenekfcb3db72010-02-18 18:52:18 +00001410 case BuiltinType::ObjCId:
1411 VisitType = Context.getObjCIdType();
1412 break;
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001413
1414 case BuiltinType::ObjCClass:
1415 VisitType = Context.getObjCClassType();
1416 break;
1417
Douglas Gregord1824312010-01-21 17:29:07 +00001418 case BuiltinType::ObjCSel:
1419 VisitType = Context.getObjCSelType();
1420 break;
1421 }
1422
1423 if (!VisitType.isNull()) {
1424 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf441baf2010-02-17 00:41:40 +00001425 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregord1824312010-01-21 17:29:07 +00001426 TU));
1427 }
1428
1429 return false;
1430}
1431
Douglas Gregor93f89952010-01-21 16:28:34 +00001432bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1433 return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
1434}
1435
Douglas Gregord1824312010-01-21 17:29:07 +00001436bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1437 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1438}
1439
1440bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1441 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1442}
1443
Douglas Gregor713602b2010-08-31 17:01:39 +00001444bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001445 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregor713602b2010-08-31 17:01:39 +00001446 // no context information with which we can match up the depth/index in the
1447 // type to the appropriate
1448 return false;
1449}
1450
Douglas Gregord1824312010-01-21 17:29:07 +00001451bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1452 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1453 return true;
1454
John McCall8b07ec22010-05-15 11:32:37 +00001455 return false;
1456}
1457
1458bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1459 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1460 return true;
1461
Douglas Gregord1824312010-01-21 17:29:07 +00001462 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1463 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1464 TU)))
1465 return true;
1466 }
1467
1468 return false;
1469}
1470
1471bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCall8b07ec22010-05-15 11:32:37 +00001472 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001473}
1474
Abramo Bagnara924a8f32010-12-10 16:29:40 +00001475bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1476 return Visit(TL.getInnerLoc());
1477}
1478
Douglas Gregord1824312010-01-21 17:29:07 +00001479bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1480 return Visit(TL.getPointeeLoc());
1481}
1482
1483bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1484 return Visit(TL.getPointeeLoc());
1485}
1486
1487bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1488 return Visit(TL.getPointeeLoc());
1489}
1490
1491bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00001492 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001493}
1494
1495bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00001496 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001497}
1498
Douglas Gregor12bca222010-08-31 14:41:23 +00001499bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1500 bool SkipResultType) {
1501 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregord1824312010-01-21 17:29:07 +00001502 return true;
1503
Douglas Gregord1824312010-01-21 17:29:07 +00001504 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek6ca136a2010-04-07 00:27:13 +00001505 if (Decl *D = TL.getArg(I))
1506 if (Visit(MakeCXCursor(D, TU)))
1507 return true;
Douglas Gregord1824312010-01-21 17:29:07 +00001508
1509 return false;
1510}
1511
1512bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1513 if (Visit(TL.getElementLoc()))
1514 return true;
1515
1516 if (Expr *Size = TL.getSizeExpr())
1517 return Visit(MakeCXCursor(Size, StmtParent, TU));
1518
1519 return false;
1520}
1521
Douglas Gregor713602b2010-08-31 17:01:39 +00001522bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1523 TemplateSpecializationTypeLoc TL) {
Douglas Gregora23e8f72010-08-31 20:37:03 +00001524 // Visit the template name.
1525 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1526 TL.getTemplateNameLoc()))
1527 return true;
Douglas Gregor713602b2010-08-31 17:01:39 +00001528
1529 // Visit the template arguments.
1530 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1531 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1532 return true;
1533
1534 return false;
1535}
1536
Douglas Gregor6479fc42010-01-21 20:48:56 +00001537bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1538 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1539}
1540
1541bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1542 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1543 return Visit(TSInfo->getTypeLoc());
1544
1545 return false;
1546}
1547
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00001548bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1549 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1550 return true;
1551
1552 return false;
1553}
1554
Douglas Gregora7a795b2011-03-01 20:11:18 +00001555bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1556 DependentTemplateSpecializationTypeLoc TL) {
1557 // Visit the nested-name-specifier, if there is one.
1558 if (TL.getQualifierLoc() &&
1559 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1560 return true;
1561
1562 // Visit the template arguments.
1563 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1564 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1565 return true;
1566
1567 return false;
1568}
1569
Douglas Gregor844cb502011-03-01 18:12:44 +00001570bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1571 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1572 return true;
1573
1574 return Visit(TL.getNamedTypeLoc());
1575}
1576
Douglas Gregord2fa7662010-12-20 02:24:11 +00001577bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1578 return Visit(TL.getPatternLoc());
1579}
1580
Ted Kremenekae9e2212010-08-27 21:34:58 +00001581bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregor14454802011-02-25 02:25:35 +00001582 // Visit the nested-name-specifier, if present.
1583 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1584 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1585 return true;
1586
Ted Kremenekae9e2212010-08-27 21:34:58 +00001587 if (D->isDefinition()) {
1588 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1589 E = D->bases_end(); I != E; ++I) {
1590 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1591 return true;
1592 }
1593 }
1594
1595 return VisitTagDecl(D);
1596}
1597
Ted Kremenek6ab9aa022010-02-18 05:46:33 +00001598bool CursorVisitor::VisitAttributes(Decl *D) {
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001599 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1600 i != e; ++i)
1601 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek6ab9aa022010-02-18 05:46:33 +00001602 return true;
1603
1604 return false;
1605}
1606
Ted Kremenek92209a42010-11-11 08:05:18 +00001607//===----------------------------------------------------------------------===//
1608// Data-recursive visitor methods.
1609//===----------------------------------------------------------------------===//
1610
Ted Kremenekacff73c2010-11-13 00:36:47 +00001611namespace {
Ted Kremenek072e6372010-11-13 00:36:50 +00001612#define DEF_JOB(NAME, DATA, KIND)\
1613class NAME : public VisitorJob {\
1614public:\
1615 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1616 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenek83900272010-11-18 00:02:32 +00001617 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek072e6372010-11-13 00:36:50 +00001618};
1619
1620DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1621DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremenek573411b2010-11-13 00:58:18 +00001622DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek072e6372010-11-13 00:36:50 +00001623DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001624DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1625 ExplicitTemplateArgsVisitKind)
Douglas Gregor557f05c2011-01-19 20:34:17 +00001626DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek072e6372010-11-13 00:36:50 +00001627#undef DEF_JOB
1628
1629class DeclVisit : public VisitorJob {
1630public:
1631 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1632 VisitorJob(parent, VisitorJob::DeclVisitKind,
1633 d, isFirst ? (void*) 1 : (void*) 0) {}
1634 static bool classof(const VisitorJob *VJ) {
Ted Kremeneke6f03042010-11-15 22:23:26 +00001635 return VJ->getKind() == DeclVisitKind;
Ted Kremenek072e6372010-11-13 00:36:50 +00001636 }
Ted Kremenek83900272010-11-18 00:02:32 +00001637 Decl *get() const { return static_cast<Decl*>(data[0]); }
1638 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek072e6372010-11-13 00:36:50 +00001639};
Ted Kremenek072e6372010-11-13 00:36:50 +00001640class TypeLocVisit : public VisitorJob {
1641public:
1642 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1643 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1644 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1645
1646 static bool classof(const VisitorJob *VJ) {
1647 return VJ->getKind() == TypeLocVisitKind;
1648 }
1649
Ted Kremeneke6f03042010-11-15 22:23:26 +00001650 TypeLoc get() const {
Ted Kremenek83900272010-11-18 00:02:32 +00001651 QualType T = QualType::getFromOpaquePtr(data[0]);
1652 return TypeLoc(T, data[1]);
Ted Kremenek072e6372010-11-13 00:36:50 +00001653 }
1654};
1655
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001656class LabelRefVisit : public VisitorJob {
1657public:
Chris Lattnerc8e630e2011-02-17 07:39:24 +00001658 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1659 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001660 labelLoc.getPtrEncoding()) {}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001661
1662 static bool classof(const VisitorJob *VJ) {
1663 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1664 }
Chris Lattnerc8e630e2011-02-17 07:39:24 +00001665 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001666 SourceLocation getLoc() const {
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001667 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenek83900272010-11-18 00:02:32 +00001668};
1669class NestedNameSpecifierVisit : public VisitorJob {
1670public:
1671 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1672 CXCursor parent)
1673 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001674 NS, R.getBegin().getPtrEncoding(),
1675 R.getEnd().getPtrEncoding()) {}
Ted Kremenek83900272010-11-18 00:02:32 +00001676 static bool classof(const VisitorJob *VJ) {
1677 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1678 }
1679 NestedNameSpecifier *get() const {
1680 return static_cast<NestedNameSpecifier*>(data[0]);
1681 }
1682 SourceRange getSourceRange() const {
1683 SourceLocation A =
1684 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1685 SourceLocation B =
1686 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1687 return SourceRange(A, B);
1688 }
1689};
Douglas Gregora6ce6082011-02-25 18:19:59 +00001690
1691class NestedNameSpecifierLocVisit : public VisitorJob {
1692public:
1693 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1694 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1695 Qualifier.getNestedNameSpecifier(),
1696 Qualifier.getOpaqueData()) { }
1697
1698 static bool classof(const VisitorJob *VJ) {
1699 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1700 }
1701
1702 NestedNameSpecifierLoc get() const {
1703 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1704 data[1]);
1705 }
1706};
1707
Ted Kremenek83900272010-11-18 00:02:32 +00001708class DeclarationNameInfoVisit : public VisitorJob {
1709public:
1710 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1711 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1714 }
1715 DeclarationNameInfo get() const {
1716 Stmt *S = static_cast<Stmt*>(data[0]);
1717 switch (S->getStmtClass()) {
1718 default:
1719 llvm_unreachable("Unhandled Stmt");
1720 case Stmt::CXXDependentScopeMemberExprClass:
1721 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1722 case Stmt::DependentScopeDeclRefExprClass:
1723 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1724 }
1725 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001726};
Ted Kremenek5d304a32010-11-18 00:42:18 +00001727class MemberRefVisit : public VisitorJob {
1728public:
1729 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1730 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001731 L.getPtrEncoding()) {}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001732 static bool classof(const VisitorJob *VJ) {
1733 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1734 }
1735 FieldDecl *get() const {
1736 return static_cast<FieldDecl*>(data[0]);
1737 }
1738 SourceLocation getLoc() const {
1739 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1740 }
1741};
Ted Kremenekacff73c2010-11-13 00:36:47 +00001742class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1743 VisitorWorkList &WL;
1744 CXCursor Parent;
1745public:
1746 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1747 : WL(wl), Parent(parent) {}
1748
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001749 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001750 void VisitBlockExpr(BlockExpr *B);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001751 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenekfdc52372010-11-13 05:38:03 +00001752 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001753 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenek83900272010-11-18 00:02:32 +00001754 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001755 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek9f49b372010-11-17 02:18:35 +00001756 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001757 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001758 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001759 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremeneka51cc432010-11-17 00:50:41 +00001760 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek79ddc672010-11-17 00:50:36 +00001761 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek7003a502010-11-17 00:50:52 +00001762 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremenek573411b2010-11-13 00:58:18 +00001763 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek072e6372010-11-13 00:36:50 +00001764 void VisitDeclStmt(DeclStmt *S);
Ted Kremenek83900272010-11-18 00:02:32 +00001765 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001766 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001767 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1768 void VisitForStmt(ForStmt *FS);
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001769 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001770 void VisitIfStmt(IfStmt *If);
1771 void VisitInitListExpr(InitListExpr *IE);
1772 void VisitMemberExpr(MemberExpr *M);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001773 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001774 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001775 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1776 void VisitOverloadExpr(OverloadExpr *E);
Peter Collingbournee190dee2011-03-11 19:24:49 +00001777 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001778 void VisitStmt(Stmt *S);
1779 void VisitSwitchStmt(SwitchStmt *S);
1780 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek513cd572010-11-17 00:50:50 +00001781 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00001782 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001783 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenekc1c30cd2010-11-17 00:50:43 +00001784 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor557f05c2011-01-19 20:34:17 +00001785 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregor820ba7b2011-01-04 17:33:58 +00001786
Ted Kremenekacff73c2010-11-13 00:36:47 +00001787private:
Ted Kremenek83900272010-11-18 00:02:32 +00001788 void AddDeclarationNameInfo(Stmt *S);
1789 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregora6ce6082011-02-25 18:19:59 +00001790 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001791 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001792 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001793 void AddStmt(Stmt *S);
Ted Kremenek072e6372010-11-13 00:36:50 +00001794 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001795 void AddTypeLoc(TypeSourceInfo *TI);
1796 void EnqueueChildren(Stmt *S);
1797};
1798} // end anonyous namespace
1799
Ted Kremenek83900272010-11-18 00:02:32 +00001800void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1801 // 'S' should always be non-null, since it comes from the
1802 // statement we are visiting.
1803 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1804}
1805void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1806 SourceRange R) {
1807 if (N)
1808 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1809}
Douglas Gregora6ce6082011-02-25 18:19:59 +00001810
1811void
1812EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1813 if (Qualifier)
1814 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1815}
1816
Ted Kremenekacff73c2010-11-13 00:36:47 +00001817void EnqueueVisitor::AddStmt(Stmt *S) {
1818 if (S)
1819 WL.push_back(StmtVisit(S, Parent));
1820}
Ted Kremenek072e6372010-11-13 00:36:50 +00001821void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00001822 if (D)
Ted Kremenek072e6372010-11-13 00:36:50 +00001823 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenekacff73c2010-11-13 00:36:47 +00001824}
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001825void EnqueueVisitor::
1826 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1827 if (A)
1828 WL.push_back(ExplicitTemplateArgsVisit(
1829 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1830}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001831void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1832 if (D)
1833 WL.push_back(MemberRefVisit(D, L, Parent));
1834}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001835void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1836 if (TI)
1837 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1838 }
1839void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremenek6a5df572010-11-12 21:34:09 +00001840 unsigned size = WL.size();
John McCall8322c3a2011-02-13 04:07:26 +00001841 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00001842 AddStmt(*Child);
Ted Kremenek6a5df572010-11-12 21:34:09 +00001843 }
1844 if (size == WL.size())
1845 return;
1846 // Now reverse the entries we just added. This will match the DFS
1847 // ordering performed by the worklist.
1848 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1849 std::reverse(I, E);
1850}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001851void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1852 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1853}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001854void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1855 AddDecl(B->getBlockDecl());
1856}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001857void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1858 EnqueueChildren(E);
1859 AddTypeLoc(E->getTypeSourceInfo());
1860}
Ted Kremenekfdc52372010-11-13 05:38:03 +00001861void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1862 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1863 E = S->body_rend(); I != E; ++I) {
1864 AddStmt(*I);
1865 }
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001866}
Ted Kremenek83900272010-11-18 00:02:32 +00001867void EnqueueVisitor::
1868VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1869 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1870 AddDeclarationNameInfo(E);
Douglas Gregore16af532011-02-28 18:50:33 +00001871 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1872 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenek83900272010-11-18 00:02:32 +00001873 if (!E->isImplicitAccess())
1874 AddStmt(E->getBase());
1875}
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001876void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1877 // Enqueue the initializer or constructor arguments.
1878 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1879 AddStmt(E->getConstructorArg(I-1));
1880 // Enqueue the array size, if any.
1881 AddStmt(E->getArraySize());
1882 // Enqueue the allocated type.
1883 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1884 // Enqueue the placement arguments.
1885 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1886 AddStmt(E->getPlacementArg(I-1));
1887}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001888void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenekbc8b3782010-11-13 05:55:56 +00001889 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1890 AddStmt(CE->getArg(I-1));
Ted Kremenekacff73c2010-11-13 00:36:47 +00001891 AddStmt(CE->getCallee());
1892 AddStmt(CE->getArg(0));
1893}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001894void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1895 // Visit the name of the type being destroyed.
1896 AddTypeLoc(E->getDestroyedTypeInfo());
1897 // Visit the scope type that looks disturbingly like the nested-name-specifier
1898 // but isn't.
1899 AddTypeLoc(E->getScopeTypeInfo());
1900 // Visit the nested-name-specifier.
Douglas Gregora6ce6082011-02-25 18:19:59 +00001901 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1902 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001903 // Visit base expression.
1904 AddStmt(E->getBase());
1905}
Ted Kremenek9f49b372010-11-17 02:18:35 +00001906void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1907 AddTypeLoc(E->getTypeSourceInfo());
1908}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001909void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1910 EnqueueChildren(E);
1911 AddTypeLoc(E->getTypeSourceInfo());
1912}
Ted Kremeneka51cc432010-11-17 00:50:41 +00001913void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1914 EnqueueChildren(E);
1915 if (E->isTypeOperand())
1916 AddTypeLoc(E->getTypeOperandSourceInfo());
1917}
Ted Kremenek79ddc672010-11-17 00:50:36 +00001918
1919void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1920 *E) {
1921 EnqueueChildren(E);
1922 AddTypeLoc(E->getTypeSourceInfo());
1923}
Ted Kremenek7003a502010-11-17 00:50:52 +00001924void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1925 EnqueueChildren(E);
1926 if (E->isTypeOperand())
1927 AddTypeLoc(E->getTypeOperandSourceInfo());
1928}
Ted Kremenek573411b2010-11-13 00:58:18 +00001929void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001930 if (DR->hasExplicitTemplateArgs()) {
1931 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1932 }
Ted Kremenek573411b2010-11-13 00:58:18 +00001933 WL.push_back(DeclRefExprParts(DR, Parent));
1934}
Ted Kremenek83900272010-11-18 00:02:32 +00001935void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1936 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1937 AddDeclarationNameInfo(E);
Douglas Gregor3a43fd62011-02-25 20:49:16 +00001938 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenek83900272010-11-18 00:02:32 +00001939}
Ted Kremenek072e6372010-11-13 00:36:50 +00001940void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1941 unsigned size = WL.size();
1942 bool isFirst = true;
1943 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1944 D != DEnd; ++D) {
1945 AddDecl(*D, isFirst);
1946 isFirst = false;
1947 }
1948 if (size == WL.size())
1949 return;
1950 // Now reverse the entries we just added. This will match the DFS
1951 // ordering performed by the worklist.
1952 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1953 std::reverse(I, E);
1954}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001955void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1956 AddStmt(E->getInit());
1957 typedef DesignatedInitExpr::Designator Designator;
1958 for (DesignatedInitExpr::reverse_designators_iterator
1959 D = E->designators_rbegin(), DEnd = E->designators_rend();
1960 D != DEnd; ++D) {
1961 if (D->isFieldDesignator()) {
1962 if (FieldDecl *Field = D->getField())
1963 AddMemberRef(Field, D->getFieldLoc());
1964 continue;
1965 }
1966 if (D->isArrayDesignator()) {
1967 AddStmt(E->getArrayIndex(*D));
1968 continue;
1969 }
1970 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1971 AddStmt(E->getArrayRangeEnd(*D));
1972 AddStmt(E->getArrayRangeStart(*D));
1973 }
1974}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001975void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1976 EnqueueChildren(E);
1977 AddTypeLoc(E->getTypeInfoAsWritten());
1978}
1979void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1980 AddStmt(FS->getBody());
1981 AddStmt(FS->getInc());
1982 AddStmt(FS->getCond());
1983 AddDecl(FS->getConditionVariable());
1984 AddStmt(FS->getInit());
1985}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001986void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1987 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1988}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001989void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
1990 AddStmt(If->getElse());
1991 AddStmt(If->getThen());
1992 AddStmt(If->getCond());
1993 AddDecl(If->getConditionVariable());
1994}
1995void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
1996 // We care about the syntactic form of the initializer list, only.
1997 if (InitListExpr *Syntactic = IE->getSyntacticForm())
1998 IE = Syntactic;
1999 EnqueueChildren(IE);
2000}
2001void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor30313cb2010-11-17 17:15:08 +00002002 WL.push_back(MemberExprParts(M, Parent));
2003
2004 // If the base of the member access expression is an implicit 'this', don't
2005 // visit it.
2006 // FIXME: If we ever want to show these implicit accesses, this will be
2007 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor25b7e052011-03-02 21:06:53 +00002008 if (!M->isImplicitAccess())
2009 AddStmt(M->getBase());
Ted Kremenekacff73c2010-11-13 00:36:47 +00002010}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00002011void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
2012 AddTypeLoc(E->getEncodedTypeSourceInfo());
2013}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002014void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
2015 EnqueueChildren(M);
2016 AddTypeLoc(M->getClassReceiverTypeInfo());
2017}
Ted Kremenek5d304a32010-11-18 00:42:18 +00002018void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2019 // Visit the components of the offsetof expression.
2020 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2021 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2022 const OffsetOfNode &Node = E->getComponent(I-1);
2023 switch (Node.getKind()) {
2024 case OffsetOfNode::Array:
2025 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2026 break;
2027 case OffsetOfNode::Field:
Abramo Bagnara6b6f0512011-03-12 09:45:03 +00002028 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenek5d304a32010-11-18 00:42:18 +00002029 break;
2030 case OffsetOfNode::Identifier:
2031 case OffsetOfNode::Base:
2032 continue;
2033 }
2034 }
2035 // Visit the type into which we're computing the offset.
2036 AddTypeLoc(E->getTypeSourceInfo());
2037}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002038void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek8eaa1652010-11-17 00:50:47 +00002039 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002040 WL.push_back(OverloadExprParts(E, Parent));
2041}
Peter Collingbournee190dee2011-03-11 19:24:49 +00002042void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2043 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek9f49b372010-11-17 02:18:35 +00002044 EnqueueChildren(E);
2045 if (E->isArgumentType())
2046 AddTypeLoc(E->getArgumentTypeInfo());
2047}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002048void EnqueueVisitor::VisitStmt(Stmt *S) {
2049 EnqueueChildren(S);
2050}
2051void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2052 AddStmt(S->getBody());
2053 AddStmt(S->getCond());
2054 AddDecl(S->getConditionVariable());
2055}
Ted Kremenekdd0d4b42010-11-17 00:50:39 +00002056
Ted Kremenekacff73c2010-11-13 00:36:47 +00002057void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2058 AddStmt(W->getBody());
2059 AddStmt(W->getCond());
2060 AddDecl(W->getConditionVariable());
2061}
Ted Kremenek513cd572010-11-17 00:50:50 +00002062void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2063 AddTypeLoc(E->getQueriedTypeSourceInfo());
2064}
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002065
2066void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002067 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichetcf7731b2010-12-08 09:11:05 +00002068 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002069}
2070
Ted Kremenekacff73c2010-11-13 00:36:47 +00002071void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2072 VisitOverloadExpr(U);
2073 if (!U->isImplicitAccess())
2074 AddStmt(U->getBase());
2075}
Ted Kremenekc1c30cd2010-11-17 00:50:43 +00002076void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2077 AddStmt(E->getSubExpr());
2078 AddTypeLoc(E->getWrittenTypeInfo());
2079}
Douglas Gregor557f05c2011-01-19 20:34:17 +00002080void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2081 WL.push_back(SizeOfPackExprParts(E, Parent));
2082}
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002083
Ted Kremenek92209a42010-11-11 08:05:18 +00002084void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00002085 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenek92209a42010-11-11 08:05:18 +00002086}
2087
2088bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2089 if (RegionOfInterest.isValid()) {
2090 SourceRange Range = getRawCursorExtent(C);
2091 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2092 return false;
2093 }
2094 return true;
2095}
2096
2097bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2098 while (!WL.empty()) {
2099 // Dequeue the worklist item.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002100 VisitorJob LI = WL.back();
2101 WL.pop_back();
2102
Ted Kremenek92209a42010-11-11 08:05:18 +00002103 // Set the Parent field, then back to its old value once we're done.
2104 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2105
2106 switch (LI.getKind()) {
Ted Kremenek73227d72010-11-12 18:26:56 +00002107 case VisitorJob::DeclVisitKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002108 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenek73227d72010-11-12 18:26:56 +00002109 if (!D)
2110 continue;
2111
2112 // For now, perform default visitation for Decls.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002113 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenek73227d72010-11-12 18:26:56 +00002114 return true;
2115
2116 continue;
2117 }
Ted Kremenek8eaa1652010-11-17 00:50:47 +00002118 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2119 const ExplicitTemplateArgumentList *ArgList =
2120 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2121 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2122 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2123 Arg != ArgEnd; ++Arg) {
2124 if (VisitTemplateArgumentLoc(*Arg))
2125 return true;
2126 }
2127 continue;
2128 }
Ted Kremeneke12bcf52010-11-12 21:34:12 +00002129 case VisitorJob::TypeLocVisitKind: {
2130 // Perform default visitation for TypeLocs.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002131 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremeneke12bcf52010-11-12 21:34:12 +00002132 return true;
2133 continue;
2134 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00002135 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerc8e630e2011-02-17 07:39:24 +00002136 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremenekc49211c2011-02-23 04:54:51 +00002137 if (LabelStmt *stmt = LS->getStmt()) {
2138 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2139 TU))) {
2140 return true;
2141 }
2142 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00002143 continue;
2144 }
Douglas Gregora6ce6082011-02-25 18:19:59 +00002145
Ted Kremenek83900272010-11-18 00:02:32 +00002146 case VisitorJob::NestedNameSpecifierVisitKind: {
2147 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2148 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2149 return true;
2150 continue;
2151 }
Douglas Gregora6ce6082011-02-25 18:19:59 +00002152
2153 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2154 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2155 if (VisitNestedNameSpecifierLoc(V->get()))
2156 return true;
2157 continue;
2158 }
2159
Ted Kremenek83900272010-11-18 00:02:32 +00002160 case VisitorJob::DeclarationNameInfoVisitKind: {
2161 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2162 ->get()))
2163 return true;
2164 continue;
2165 }
Ted Kremenek5d304a32010-11-18 00:42:18 +00002166 case VisitorJob::MemberRefVisitKind: {
2167 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2168 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2169 return true;
2170 continue;
2171 }
Ted Kremenek92209a42010-11-11 08:05:18 +00002172 case VisitorJob::StmtVisitKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002173 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek7716cd62010-11-11 23:11:43 +00002174 if (!S)
2175 continue;
2176
Ted Kremenek73227d72010-11-12 18:26:56 +00002177 // Update the current cursor.
Ted Kremenek92209a42010-11-11 08:05:18 +00002178 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenek5d304a32010-11-18 00:42:18 +00002179 if (!IsInRegionOfInterest(Cursor))
2180 continue;
2181 switch (Visitor(Cursor, Parent, ClientData)) {
2182 case CXChildVisit_Break: return true;
2183 case CXChildVisit_Continue: break;
2184 case CXChildVisit_Recurse:
2185 EnqueueWorkList(WL, S);
Ted Kremeneke6f03042010-11-15 22:23:26 +00002186 break;
Ted Kremenek92209a42010-11-11 08:05:18 +00002187 }
Ted Kremeneke6f03042010-11-15 22:23:26 +00002188 continue;
Ted Kremenek92209a42010-11-11 08:05:18 +00002189 }
2190 case VisitorJob::MemberExprPartsKind: {
2191 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002192 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenek92209a42010-11-11 08:05:18 +00002193
2194 // Visit the nested-name-specifier
Douglas Gregorea972d32011-02-28 21:54:11 +00002195 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2196 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek92209a42010-11-11 08:05:18 +00002197 return true;
2198
2199 // Visit the declaration name.
2200 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2201 return true;
2202
2203 // Visit the explicitly-specified template arguments, if any.
2204 if (M->hasExplicitTemplateArgs()) {
2205 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2206 *ArgEnd = Arg + M->getNumTemplateArgs();
2207 Arg != ArgEnd; ++Arg) {
2208 if (VisitTemplateArgumentLoc(*Arg))
2209 return true;
2210 }
2211 }
2212 continue;
2213 }
Ted Kremenek573411b2010-11-13 00:58:18 +00002214 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002215 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremenek573411b2010-11-13 00:58:18 +00002216 // Visit nested-name-specifier, if present.
Douglas Gregorea972d32011-02-28 21:54:11 +00002217 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2218 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek573411b2010-11-13 00:58:18 +00002219 return true;
2220 // Visit declaration name.
2221 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2222 return true;
Ted Kremenek573411b2010-11-13 00:58:18 +00002223 continue;
2224 }
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002225 case VisitorJob::OverloadExprPartsKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002226 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002227 // Visit the nested-name-specifier.
Douglas Gregor0da1d432011-02-28 20:01:57 +00002228 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2229 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002230 return true;
2231 // Visit the declaration name.
2232 if (VisitDeclarationNameInfo(O->getNameInfo()))
2233 return true;
2234 // Visit the overloaded declaration reference.
2235 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2236 return true;
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002237 continue;
2238 }
Douglas Gregor557f05c2011-01-19 20:34:17 +00002239 case VisitorJob::SizeOfPackExprPartsKind: {
2240 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2241 NamedDecl *Pack = E->getPack();
2242 if (isa<TemplateTypeParmDecl>(Pack)) {
2243 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2244 E->getPackLoc(), TU)))
2245 return true;
2246
2247 continue;
2248 }
2249
2250 if (isa<TemplateTemplateParmDecl>(Pack)) {
2251 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2252 E->getPackLoc(), TU)))
2253 return true;
2254
2255 continue;
2256 }
2257
2258 // Non-type template parameter packs and function parameter packs are
2259 // treated like DeclRefExpr cursors.
2260 continue;
2261 }
Ted Kremenek92209a42010-11-11 08:05:18 +00002262 }
2263 }
2264 return false;
2265}
2266
Ted Kremenek5d304a32010-11-18 00:42:18 +00002267bool CursorVisitor::Visit(Stmt *S) {
Ted Kremeneka4c27ec2010-11-15 23:31:32 +00002268 VisitorWorkList *WL = 0;
2269 if (!WorkListFreeList.empty()) {
2270 WL = WorkListFreeList.back();
2271 WL->clear();
2272 WorkListFreeList.pop_back();
2273 }
2274 else {
2275 WL = new VisitorWorkList();
2276 WorkListCache.push_back(WL);
2277 }
2278 EnqueueWorkList(*WL, S);
2279 bool result = RunVisitorWorkList(*WL);
2280 WorkListFreeList.push_back(WL);
2281 return result;
Ted Kremenek92209a42010-11-11 08:05:18 +00002282}
2283
2284//===----------------------------------------------------------------------===//
2285// Misc. API hooks.
2286//===----------------------------------------------------------------------===//
2287
Douglas Gregor2c844822010-09-24 21:18:36 +00002288static llvm::sys::Mutex EnableMultithreadingMutex;
2289static bool EnabledMultithreading;
2290
Benjamin Kramer61f5d0c2009-10-18 16:11:04 +00002291extern "C" {
Douglas Gregor1e21cc72010-02-18 23:07:20 +00002292CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2293 int displayDiagnostics) {
Daniel Dunbara5af410d2010-10-08 19:30:33 +00002294 // Disable pretty stack trace functionality, which will otherwise be a very
2295 // poor citizen of the world and set up all sorts of signal handlers.
2296 llvm::DisablePrettyStackTrace = true;
2297
Daniel Dunbarc91f2ff2010-08-18 18:43:14 +00002298 // We use crash recovery to make some of our APIs more reliable, implicitly
2299 // enable it.
2300 llvm::CrashRecoveryContext::Enable();
2301
Douglas Gregor2c844822010-09-24 21:18:36 +00002302 // Enable support for multithreading in LLVM.
2303 {
2304 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2305 if (!EnabledMultithreading) {
2306 llvm::llvm_start_multithreaded();
2307 EnabledMultithreading = true;
2308 }
2309 }
2310
Douglas Gregor87752492010-01-22 20:35:53 +00002311 CIndexer *CIdxr = new CIndexer();
Steve Naroff531e2842009-10-20 14:46:24 +00002312 if (excludeDeclarationsFromPCH)
2313 CIdxr->setOnlyLocalDecls();
Douglas Gregor1e21cc72010-02-18 23:07:20 +00002314 if (displayDiagnostics)
2315 CIdxr->setDisplayDiagnostics();
Steve Naroff531e2842009-10-20 14:46:24 +00002316 return CIdxr;
Steve Naroffd5e8e862009-08-27 19:51:58 +00002317}
2318
Daniel Dunbar079203f2009-12-01 03:14:51 +00002319void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002320 if (CIdx)
2321 delete static_cast<CIndexer *>(CIdx);
Steve Naroff3aa2d732009-09-17 18:33:27 +00002322}
2323
Ted Kremenek1ec7b332011-03-18 23:05:39 +00002324void clang_toggleCrashRecovery(unsigned isEnabled) {
2325 if (isEnabled)
2326 llvm::CrashRecoveryContext::Enable();
2327 else
2328 llvm::CrashRecoveryContext::Disable();
2329}
2330
Daniel Dunbar079203f2009-12-01 03:14:51 +00002331CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002332 const char *ast_filename) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002333 if (!CIdx)
2334 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002335
Douglas Gregor16bef852009-10-16 20:01:17 +00002336 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis71731d62010-11-03 22:45:23 +00002337 FileSystemOptions FileSystemOpts;
2338 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002339
Douglas Gregor7f95d262010-04-05 23:52:57 +00002340 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremenek91554282010-11-16 08:15:36 +00002341 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002342 CXXIdx->getOnlyLocalDecls(),
2343 0, 0, true);
Ted Kremenek91554282010-11-16 08:15:36 +00002344 return MakeCXTranslationUnit(TU);
Steve Naroffd5e8e862009-08-27 19:51:58 +00002345}
2346
Douglas Gregor4a47bca2010-08-09 22:28:58 +00002347unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor176d2862010-09-27 05:49:58 +00002348 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregorf5a18542010-10-27 17:24:53 +00002349 CXTranslationUnit_CacheCompletionResults |
2350 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregor4a47bca2010-08-09 22:28:58 +00002351}
2352
Daniel Dunbar079203f2009-12-01 03:14:51 +00002353CXTranslationUnit
2354clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2355 const char *source_filename,
2356 int num_command_line_args,
Douglas Gregor57879fa2010-09-01 16:43:19 +00002357 const char * const *command_line_args,
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002358 unsigned num_unsaved_files,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002359 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor99d2cf42010-07-21 18:52:53 +00002360 return clang_parseTranslationUnit(CIdx, source_filename,
2361 command_line_args, num_command_line_args,
2362 unsaved_files, num_unsaved_files,
2363 CXTranslationUnit_DetailedPreprocessingRecord);
2364}
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002365
2366struct ParseTranslationUnitInfo {
2367 CXIndex CIdx;
2368 const char *source_filename;
Douglas Gregor57879fa2010-09-01 16:43:19 +00002369 const char *const *command_line_args;
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002370 int num_command_line_args;
2371 struct CXUnsavedFile *unsaved_files;
2372 unsigned num_unsaved_files;
2373 unsigned options;
2374 CXTranslationUnit result;
2375};
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002376static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002377 ParseTranslationUnitInfo *PTUI =
2378 static_cast<ParseTranslationUnitInfo*>(UserData);
2379 CXIndex CIdx = PTUI->CIdx;
2380 const char *source_filename = PTUI->source_filename;
Douglas Gregor57879fa2010-09-01 16:43:19 +00002381 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002382 int num_command_line_args = PTUI->num_command_line_args;
2383 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2384 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2385 unsigned options = PTUI->options;
2386 PTUI->result = 0;
Douglas Gregor99d2cf42010-07-21 18:52:53 +00002387
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002388 if (!CIdx)
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002389 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002390
Steve Naroff531e2842009-10-20 14:46:24 +00002391 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2392
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002393 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregor028d3e42010-08-09 20:45:32 +00002394 bool CompleteTranslationUnit
2395 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregorb14904c2010-08-13 22:48:40 +00002396 bool CacheCodeCompetionResults
2397 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregorf5a18542010-10-27 17:24:53 +00002398 bool CXXPrecompilePreamble
2399 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2400 bool CXXChainedPCH
2401 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregorb14904c2010-08-13 22:48:40 +00002402
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002403 // Configure the diagnostics.
2404 DiagnosticOptions DiagOpts;
Ted Kremenek022a4902011-03-22 01:15:24 +00002405 llvm::IntrusiveRefCntPtr<Diagnostic>
2406 Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2407 command_line_args));
Ted Kremenekf441baf2010-02-17 00:41:40 +00002408
Ted Kremenek022a4902011-03-22 01:15:24 +00002409 // Recover resources if we crash before exiting this function.
2410 llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
2411 llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
2412 DiagCleanup(Diags.getPtr());
2413
2414 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2415 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2416
2417 // Recover resources if we crash before exiting this function.
2418 llvm::CrashRecoveryContextCleanupRegistrar<
2419 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2420
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002421 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattner58c79342010-04-05 22:42:27 +00002422 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002423 const llvm::MemoryBuffer *Buffer
Chris Lattner58c79342010-04-05 22:42:27 +00002424 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek022a4902011-03-22 01:15:24 +00002425 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2426 Buffer));
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002427 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00002428
Ted Kremenek022a4902011-03-22 01:15:24 +00002429 llvm::OwningPtr<std::vector<const char *> >
2430 Args(new std::vector<const char*>());
2431
2432 // Recover resources if we crash before exiting this method.
2433 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2434 ArgsCleanup(Args.get());
2435
Douglas Gregor79edde82010-07-09 18:39:07 +00002436 // Since the Clang C library is primarily used by batch tools dealing with
2437 // (often very broken) source code, where spell-checking can have a
2438 // significant negative impact on performance (particularly when
2439 // precompiled headers are involved), we disable it by default.
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002440 // Only do this if we haven't found a spell-checking-related argument.
2441 bool FoundSpellCheckingArgument = false;
2442 for (int I = 0; I != num_command_line_args; ++I) {
2443 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2444 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2445 FoundSpellCheckingArgument = true;
2446 break;
Steve Naroff531e2842009-10-20 14:46:24 +00002447 }
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002448 }
2449 if (!FoundSpellCheckingArgument)
Ted Kremenek022a4902011-03-22 01:15:24 +00002450 Args->push_back("-fno-spell-checking");
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002451
Ted Kremenek022a4902011-03-22 01:15:24 +00002452 Args->insert(Args->end(), command_line_args,
2453 command_line_args + num_command_line_args);
Douglas Gregorac0605e2010-01-28 06:00:51 +00002454
Argyrios Kyrtzidise7620202011-03-20 18:17:52 +00002455 // The 'source_filename' argument is optional. If the caller does not
2456 // specify it then it is assumed that the source file is specified
2457 // in the actual argument list.
2458 // Put the source file after command_line_args otherwise if '-x' flag is
2459 // present it will be unused.
2460 if (source_filename)
Ted Kremenek022a4902011-03-22 01:15:24 +00002461 Args->push_back(source_filename);
Argyrios Kyrtzidise7620202011-03-20 18:17:52 +00002462
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002463 // Do we need the detailed preprocessing record?
2464 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Ted Kremenek022a4902011-03-22 01:15:24 +00002465 Args->push_back("-Xclang");
2466 Args->push_back("-detailed-preprocessing-record");
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002467 }
2468
Argyrios Kyrtzidis8d5038c2010-11-18 21:47:04 +00002469 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002470 llvm::OwningPtr<ASTUnit> Unit(
Ted Kremenek600b54c2011-03-22 20:16:19 +00002471 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2472 /* vector::data() not portable */,
2473 Args->size() ? (&(*Args)[0] + Args->size()) :0,
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002474 Diags,
2475 CXXIdx->getClangResourcesPath(),
2476 CXXIdx->getOnlyLocalDecls(),
Douglas Gregor44c6ee72010-11-11 00:39:14 +00002477 /*CaptureDiagnostics=*/true,
Ted Kremenek600b54c2011-03-22 20:16:19 +00002478 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
Ted Kremenek022a4902011-03-22 01:15:24 +00002479 RemappedFiles->size(),
Argyrios Kyrtzidis97d3a382011-03-08 23:35:24 +00002480 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002481 PrecompilePreamble,
2482 CompleteTranslationUnit,
Douglas Gregorf5a18542010-10-27 17:24:53 +00002483 CacheCodeCompetionResults,
2484 CXXPrecompilePreamble,
2485 CXXChainedPCH));
Ted Kremenekf441baf2010-02-17 00:41:40 +00002486
Argyrios Kyrtzidis8d5038c2010-11-18 21:47:04 +00002487 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002488 // Make sure to check that 'Unit' is non-NULL.
2489 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2490 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2491 DEnd = Unit->stored_diag_end();
2492 D != DEnd; ++D) {
2493 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2494 CXString Msg = clang_formatDiagnostic(&Diag,
2495 clang_defaultDiagnosticDisplayOptions());
2496 fprintf(stderr, "%s\n", clang_getCString(Msg));
2497 clang_disposeString(Msg);
2498 }
Douglas Gregord770f732010-02-22 23:17:23 +00002499#ifdef LLVM_ON_WIN32
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002500 // On Windows, force a flush, since there may be multiple copies of
2501 // stderr and stdout in the file system, all with different buffers
2502 // but writing to the same device.
2503 fflush(stderr);
2504#endif
2505 }
Douglas Gregor33cdd812010-02-18 18:08:43 +00002506 }
Douglas Gregorac0605e2010-01-28 06:00:51 +00002507
Ted Kremenek91554282010-11-16 08:15:36 +00002508 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002509}
2510CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2511 const char *source_filename,
Douglas Gregor57879fa2010-09-01 16:43:19 +00002512 const char * const *command_line_args,
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002513 int num_command_line_args,
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002514 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002515 unsigned num_unsaved_files,
2516 unsigned options) {
2517 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002518 num_command_line_args, unsaved_files,
2519 num_unsaved_files, options, 0 };
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002520 llvm::CrashRecoveryContext CRC;
2521
Daniel Dunbarb7383e62010-11-05 07:19:31 +00002522 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbarf10f9be2010-08-23 22:35:34 +00002523 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2524 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2525 fprintf(stderr, " 'command_line_args' : [");
2526 for (int i = 0; i != num_command_line_args; ++i) {
2527 if (i)
2528 fprintf(stderr, ", ");
2529 fprintf(stderr, "'%s'", command_line_args[i]);
2530 }
2531 fprintf(stderr, "],\n");
2532 fprintf(stderr, " 'unsaved_files' : [");
2533 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2534 if (i)
2535 fprintf(stderr, ", ");
2536 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2537 unsaved_files[i].Length);
2538 }
2539 fprintf(stderr, "],\n");
2540 fprintf(stderr, " 'options' : %d,\n", options);
2541 fprintf(stderr, "}\n");
2542
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002543 return 0;
2544 }
2545
2546 return PTUI.result;
Steve Naroff7781daa2009-10-15 20:04:39 +00002547}
2548
Douglas Gregor6bb92ec2010-08-13 15:35:05 +00002549unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2550 return CXSaveTranslationUnit_None;
2551}
2552
2553int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2554 unsigned options) {
Douglas Gregore9386682010-08-13 05:36:37 +00002555 if (!TU)
2556 return 1;
2557
Ted Kremenek91554282010-11-16 08:15:36 +00002558 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregore9386682010-08-13 05:36:37 +00002559}
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002560
Daniel Dunbar079203f2009-12-01 03:14:51 +00002561void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002562 if (CTUnit) {
2563 // If the translation unit has been marked as unsafe to free, just discard
2564 // it.
Ted Kremenek91554282010-11-16 08:15:36 +00002565 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002566 return;
2567
Ted Kremenek91554282010-11-16 08:15:36 +00002568 delete static_cast<ASTUnit *>(CTUnit->TUData);
2569 disposeCXStringPool(CTUnit->StringPool);
2570 delete CTUnit;
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002571 }
Steve Naroff3aa2d732009-09-17 18:33:27 +00002572}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002573
Douglas Gregorde051182010-08-11 15:58:42 +00002574unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2575 return CXReparse_None;
2576}
2577
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002578struct ReparseTranslationUnitInfo {
2579 CXTranslationUnit TU;
2580 unsigned num_unsaved_files;
2581 struct CXUnsavedFile *unsaved_files;
2582 unsigned options;
2583 int result;
2584};
Douglas Gregorca5b0532010-09-23 18:47:53 +00002585
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002586static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002587 ReparseTranslationUnitInfo *RTUI =
2588 static_cast<ReparseTranslationUnitInfo*>(UserData);
2589 CXTranslationUnit TU = RTUI->TU;
2590 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2591 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2592 unsigned options = RTUI->options;
2593 (void) options;
2594 RTUI->result = 1;
2595
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002596 if (!TU)
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002597 return;
Douglas Gregorca5b0532010-09-23 18:47:53 +00002598
Ted Kremenek91554282010-11-16 08:15:36 +00002599 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorca5b0532010-09-23 18:47:53 +00002600 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002601
Ted Kremenek022a4902011-03-22 01:15:24 +00002602 llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
2603 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2604
2605 // Recover resources if we crash before exiting this function.
2606 llvm::CrashRecoveryContextCleanupRegistrar<
2607 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2608
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002609 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2610 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2611 const llvm::MemoryBuffer *Buffer
Douglas Gregor8e984da2010-08-04 16:47:14 +00002612 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Ted Kremenek022a4902011-03-22 01:15:24 +00002613 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2614 Buffer));
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002615 }
2616
Ted Kremenek600b54c2011-03-22 20:16:19 +00002617 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2618 RemappedFiles->size()))
Douglas Gregorca5b0532010-09-23 18:47:53 +00002619 RTUI->result = 0;
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002620}
Douglas Gregorca5b0532010-09-23 18:47:53 +00002621
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002622int clang_reparseTranslationUnit(CXTranslationUnit TU,
2623 unsigned num_unsaved_files,
2624 struct CXUnsavedFile *unsaved_files,
2625 unsigned options) {
2626 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2627 options, 0 };
2628 llvm::CrashRecoveryContext CRC;
2629
Daniel Dunbarb7383e62010-11-05 07:19:31 +00002630 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002631 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremenek91554282010-11-16 08:15:36 +00002632 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002633 return 1;
2634 }
2635
Ted Kremenek55ccf4e2010-10-29 01:06:50 +00002636
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002637 return RTUI.result;
2638}
2639
Douglas Gregor028d3e42010-08-09 20:45:32 +00002640
Daniel Dunbar079203f2009-12-01 03:14:51 +00002641CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002642 if (!CTUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002643 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00002644
Ted Kremenek91554282010-11-16 08:15:36 +00002645 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002646 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroff38c1a7b2009-09-03 15:49:00 +00002647}
Daniel Dunbare58bd8b2009-08-28 16:30:07 +00002648
Douglas Gregord2fc7272010-01-20 00:23:15 +00002649CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00002650 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregord2fc7272010-01-20 00:23:15 +00002651 return Result;
2652}
2653
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002654} // end: extern "C"
Steve Naroffd5e8e862009-08-27 19:51:58 +00002655
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002656//===----------------------------------------------------------------------===//
Douglas Gregor4f46e782010-01-19 21:36:55 +00002657// CXSourceLocation and CXSourceRange Operations.
2658//===----------------------------------------------------------------------===//
2659
Douglas Gregor816fd362010-01-22 21:44:22 +00002660extern "C" {
2661CXSourceLocation clang_getNullLocation() {
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002662 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregor816fd362010-01-22 21:44:22 +00002663 return Result;
2664}
2665
2666unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar83a23542010-01-30 23:58:27 +00002667 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2668 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2669 loc1.int_data == loc2.int_data);
Douglas Gregor816fd362010-01-22 21:44:22 +00002670}
2671
2672CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2673 CXFile file,
2674 unsigned line,
2675 unsigned column) {
Douglas Gregor0925fbc2010-04-30 19:45:53 +00002676 if (!tu || !file)
Douglas Gregor816fd362010-01-22 21:44:22 +00002677 return clang_getNullLocation();
Douglas Gregor0925fbc2010-04-30 19:45:53 +00002678
Douglas Gregore6642762011-02-03 17:17:35 +00002679 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremenek91554282010-11-16 08:15:36 +00002680 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregore6642762011-02-03 17:17:35 +00002681 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregor816fd362010-01-22 21:44:22 +00002682 SourceLocation SLoc
Douglas Gregore6642762011-02-03 17:17:35 +00002683 = CXXUnit->getSourceManager().getLocation(File, line, column);
2684 if (SLoc.isInvalid()) {
2685 if (Logging)
2686 llvm::errs() << "clang_getLocation(\"" << File->getName()
2687 << "\", " << line << ", " << column << ") = invalid\n";
2688 return clang_getNullLocation();
2689 }
2690
2691 if (Logging)
2692 llvm::errs() << "clang_getLocation(\"" << File->getName()
2693 << "\", " << line << ", " << column << ") = "
2694 << SLoc.getRawEncoding() << "\n";
David Chisnall2e16ac52010-10-15 17:07:39 +00002695
2696 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2697}
2698
2699CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2700 CXFile file,
2701 unsigned offset) {
2702 if (!tu || !file)
2703 return clang_getNullLocation();
2704
Ted Kremenek91554282010-11-16 08:15:36 +00002705 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall2e16ac52010-10-15 17:07:39 +00002706 SourceLocation Start
2707 = CXXUnit->getSourceManager().getLocation(
2708 static_cast<const FileEntry *>(file),
2709 1, 1);
2710 if (Start.isInvalid()) return clang_getNullLocation();
2711
2712 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2713
2714 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002715
Ted Kremenek54140272010-06-28 23:54:17 +00002716 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregor816fd362010-01-22 21:44:22 +00002717}
2718
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002719CXSourceRange clang_getNullRange() {
2720 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2721 return Result;
2722}
Daniel Dunbar02968e52010-02-14 10:02:57 +00002723
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002724CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2725 if (begin.ptr_data[0] != end.ptr_data[0] ||
2726 begin.ptr_data[1] != end.ptr_data[1])
2727 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002728
2729 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002730 begin.int_data, end.int_data };
Douglas Gregor816fd362010-01-22 21:44:22 +00002731 return Result;
2732}
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002733} // end: extern "C"
Douglas Gregor816fd362010-01-22 21:44:22 +00002734
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002735static void createNullLocation(CXFile *file, unsigned *line,
2736 unsigned *column, unsigned *offset) {
2737 if (file)
2738 *file = 0;
2739 if (line)
2740 *line = 0;
2741 if (column)
2742 *column = 0;
2743 if (offset)
2744 *offset = 0;
2745 return;
2746}
2747
2748extern "C" {
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002749void clang_getInstantiationLocation(CXSourceLocation location,
2750 CXFile *file,
2751 unsigned *line,
2752 unsigned *column,
2753 unsigned *offset) {
Douglas Gregor4f46e782010-01-19 21:36:55 +00002754 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2755
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002756 if (!location.ptr_data[0] || Loc.isInvalid()) {
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002757 createNullLocation(file, line, column, offset);
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002758 return;
2759 }
2760
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002761 const SourceManager &SM =
2762 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002763 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002764
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002765 // Check that the FileID is invalid on the instantiation location.
2766 // This can manifest in invalid code.
2767 FileID fileID = SM.getFileID(InstLoc);
2768 const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID);
2769 if (!sloc.isFile()) {
2770 createNullLocation(file, line, column, offset);
2771 return;
2772 }
2773
Douglas Gregor4f46e782010-01-19 21:36:55 +00002774 if (file)
Ted Kremenek1ba9bbc2011-03-23 02:16:44 +00002775 *file = (void *)SM.getFileEntryForSLocEntry(sloc);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002776 if (line)
2777 *line = SM.getInstantiationLineNumber(InstLoc);
2778 if (column)
2779 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregor47751d62010-01-26 03:07:15 +00002780 if (offset)
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002781 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregor47751d62010-01-26 03:07:15 +00002782}
2783
Douglas Gregor229bebd2010-11-09 06:24:54 +00002784void clang_getSpellingLocation(CXSourceLocation location,
2785 CXFile *file,
2786 unsigned *line,
2787 unsigned *column,
2788 unsigned *offset) {
2789 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2790
2791 if (!location.ptr_data[0] || Loc.isInvalid()) {
2792 if (file)
2793 *file = 0;
2794 if (line)
2795 *line = 0;
2796 if (column)
2797 *column = 0;
2798 if (offset)
2799 *offset = 0;
2800 return;
2801 }
2802
2803 const SourceManager &SM =
2804 *static_cast<const SourceManager*>(location.ptr_data[0]);
2805 SourceLocation SpellLoc = Loc;
2806 if (SpellLoc.isMacroID()) {
2807 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2808 if (SimpleSpellingLoc.isFileID() &&
2809 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2810 SpellLoc = SimpleSpellingLoc;
2811 else
2812 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2813 }
2814
2815 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2816 FileID FID = LocInfo.first;
2817 unsigned FileOffset = LocInfo.second;
2818
2819 if (file)
2820 *file = (void *)SM.getFileEntryForID(FID);
2821 if (line)
2822 *line = SM.getLineNumber(FID, FileOffset);
2823 if (column)
2824 *column = SM.getColumnNumber(FID, FileOffset);
2825 if (offset)
2826 *offset = FileOffset;
2827}
2828
Douglas Gregor4f46e782010-01-19 21:36:55 +00002829CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002830 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002831 range.begin_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002832 return Result;
2833}
2834
2835CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002836 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002837 range.end_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002838 return Result;
2839}
2840
Douglas Gregor816fd362010-01-22 21:44:22 +00002841} // end: extern "C"
2842
Douglas Gregor4f46e782010-01-19 21:36:55 +00002843//===----------------------------------------------------------------------===//
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002844// CXFile Operations.
2845//===----------------------------------------------------------------------===//
2846
2847extern "C" {
Ted Kremenekc560b682010-02-17 00:41:20 +00002848CXString clang_getFileName(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002849 if (!SFile)
Ted Kremenek91554282010-11-16 08:15:36 +00002850 return createCXString((const char*)NULL);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002851
Steve Naroff6231f182009-10-27 14:35:18 +00002852 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenekc560b682010-02-17 00:41:20 +00002853 return createCXString(FEnt->getName());
Steve Naroff6231f182009-10-27 14:35:18 +00002854}
2855
2856time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002857 if (!SFile)
2858 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002859
Steve Naroff6231f182009-10-27 14:35:18 +00002860 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2861 return FEnt->getModificationTime();
Steve Naroff26760892009-09-25 21:45:39 +00002862}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002863
Douglas Gregor816fd362010-01-22 21:44:22 +00002864CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2865 if (!tu)
2866 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002867
Ted Kremenek91554282010-11-16 08:15:36 +00002868 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002869
Douglas Gregor816fd362010-01-22 21:44:22 +00002870 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner5159f612010-11-23 08:35:12 +00002871 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregor816fd362010-01-22 21:44:22 +00002872}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002873
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002874} // end: extern "C"
Steve Naroff26760892009-09-25 21:45:39 +00002875
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002876//===----------------------------------------------------------------------===//
2877// CXCursor Operations.
2878//===----------------------------------------------------------------------===//
2879
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002880static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregore6712982010-10-01 21:11:22 +00002881 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2882 return getDeclFromExpr(CE->getSubExpr());
2883
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002884 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2885 return RefExpr->getDecl();
Douglas Gregor263803a2010-10-22 22:24:08 +00002886 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2887 return RefExpr->getDecl();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002888 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2889 return ME->getMemberDecl();
2890 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2891 return RE->getDecl();
Douglas Gregore6712982010-10-01 21:11:22 +00002892 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCallb7bd14f2010-12-02 01:19:52 +00002893 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregore6712982010-10-01 21:11:22 +00002894
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002895 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2896 return getDeclFromExpr(CE->getCallee());
Douglas Gregor16443fd2010-11-05 21:11:19 +00002897 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2898 if (!CE->isElidable())
2899 return CE->getConstructor();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002900 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2901 return OME->getMethodDecl();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002902
Douglas Gregore6712982010-10-01 21:11:22 +00002903 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2904 return PE->getProtocol();
Douglas Gregorcdbc5392011-01-15 01:15:58 +00002905 if (SubstNonTypeTemplateParmPackExpr *NTTP
2906 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2907 return NTTP->getParameterPack();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002908 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2909 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2910 isa<ParmVarDecl>(SizeOfPack->getPack()))
2911 return SizeOfPack->getPack();
Douglas Gregore6712982010-10-01 21:11:22 +00002912
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002913 return 0;
2914}
2915
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002916static SourceLocation getLocationFromExpr(Expr *E) {
2917 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2918 return /*FIXME:*/Msg->getLeftLoc();
2919 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2920 return DRE->getLocation();
Douglas Gregor263803a2010-10-22 22:24:08 +00002921 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2922 return RefExpr->getLocation();
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002923 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2924 return Member->getMemberLoc();
2925 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2926 return Ivar->getLocation();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002927 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2928 return SizeOfPack->getPackLoc();
2929
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002930 return E->getLocStart();
2931}
2932
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002933extern "C" {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002934
2935unsigned clang_visitChildren(CXCursor parent,
Douglas Gregor71f3d942010-01-20 20:59:29 +00002936 CXCursorVisitor visitor,
2937 CXClientData client_data) {
Ted Kremenek91554282010-11-16 08:15:36 +00002938 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
Douglas Gregorc2b97992011-03-16 23:23:30 +00002939 getCursorASTUnit(parent)->getMaxPCHLevel(),
2940 false);
Douglas Gregor71f3d942010-01-20 20:59:29 +00002941 return CursorVis.VisitChildren(parent);
2942}
2943
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002944#ifndef __has_feature
2945#define __has_feature(x) 0
2946#endif
2947#if __has_feature(blocks)
2948typedef enum CXChildVisitResult
2949 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2950
2951static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2952 CXClientData client_data) {
2953 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2954 return block(cursor, parent);
2955}
2956#else
2957// If we are compiled with a compiler that doesn't have native blocks support,
2958// define and call the block manually, so the
2959typedef struct _CXChildVisitResult
2960{
2961 void *isa;
2962 int flags;
2963 int reserved;
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002964 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2965 CXCursor);
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002966} *CXCursorVisitorBlock;
2967
2968static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2969 CXClientData client_data) {
2970 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2971 return block->invoke(block, cursor, parent);
2972}
2973#endif
2974
2975
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002976unsigned clang_visitChildrenWithBlock(CXCursor parent,
2977 CXCursorVisitorBlock block) {
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002978 return clang_visitChildren(parent, visitWithBlock, block);
2979}
2980
Douglas Gregordd969c82010-01-20 21:45:58 +00002981static CXString getDeclSpelling(Decl *D) {
2982 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002983 if (!ND) {
2984 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2985 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2986 return createCXString(Property->getIdentifier()->getName());
2987
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002988 return createCXString("");
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002989 }
2990
Douglas Gregordd969c82010-01-20 21:45:58 +00002991 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002992 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf441baf2010-02-17 00:41:40 +00002993
Douglas Gregordd969c82010-01-20 21:45:58 +00002994 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2995 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2996 // and returns different names. NamedDecl returns the class name and
2997 // ObjCCategoryImplDecl returns the category name.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002998 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf441baf2010-02-17 00:41:40 +00002999
Douglas Gregor01a430132010-09-01 03:07:18 +00003000 if (isa<UsingDirectiveDecl>(D))
3001 return createCXString("");
3002
Ted Kremenek08de5c12010-05-19 21:51:10 +00003003 llvm::SmallString<1024> S;
3004 llvm::raw_svector_ostream os(S);
3005 ND->printName(os);
3006
3007 return createCXString(os.str());
Douglas Gregordd969c82010-01-20 21:45:58 +00003008}
Ted Kremenekf441baf2010-02-17 00:41:40 +00003009
Daniel Dunbar079203f2009-12-01 03:14:51 +00003010CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregord2fc7272010-01-20 00:23:15 +00003011 if (clang_isTranslationUnit(C.kind))
Ted Kremenek91554282010-11-16 08:15:36 +00003012 return clang_getTranslationUnitSpelling(
3013 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregord2fc7272010-01-20 00:23:15 +00003014
Steve Naroff80a766b2009-09-02 18:26:48 +00003015 if (clang_isReference(C.kind)) {
3016 switch (C.kind) {
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003017 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor6c8959b2010-01-16 14:00:32 +00003018 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003019 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003020 }
3021 case CXCursor_ObjCClassRef: {
Douglas Gregor46d66142010-01-16 17:14:40 +00003022 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003023 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003024 }
3025 case CXCursor_ObjCProtocolRef: {
Douglas Gregoref6eb842010-01-16 15:44:18 +00003026 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003027 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003028 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003029 }
Ted Kremenekae9e2212010-08-27 21:34:58 +00003030 case CXCursor_CXXBaseSpecifier: {
3031 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3032 return createCXString(B->getType().getAsString());
3033 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003034 case CXCursor_TypeRef: {
3035 TypeDecl *Type = getCursorTypeRef(C).first;
3036 assert(Type && "Missing type decl");
3037
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003038 return createCXString(getCursorContext(C).getTypeDeclType(Type).
3039 getAsString());
Douglas Gregor93f89952010-01-21 16:28:34 +00003040 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00003041 case CXCursor_TemplateRef: {
3042 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregora89314e2010-08-31 23:48:11 +00003043 assert(Template && "Missing template decl");
Douglas Gregora23e8f72010-08-31 20:37:03 +00003044
3045 return createCXString(Template->getNameAsString());
3046 }
Douglas Gregora89314e2010-08-31 23:48:11 +00003047
3048 case CXCursor_NamespaceRef: {
3049 NamedDecl *NS = getCursorNamespaceRef(C).first;
3050 assert(NS && "Missing namespace decl");
3051
3052 return createCXString(NS->getNameAsString());
3053 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003054
Douglas Gregorf3af3112010-09-09 21:42:20 +00003055 case CXCursor_MemberRef: {
3056 FieldDecl *Field = getCursorMemberRef(C).first;
3057 assert(Field && "Missing member decl");
3058
3059 return createCXString(Field->getNameAsString());
3060 }
3061
Douglas Gregora93ab662010-09-10 00:22:18 +00003062 case CXCursor_LabelRef: {
3063 LabelStmt *Label = getCursorLabelRef(C).first;
3064 assert(Label && "Missing label");
3065
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003066 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00003067 }
3068
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003069 case CXCursor_OverloadedDeclRef: {
3070 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3071 if (Decl *D = Storage.dyn_cast<Decl *>()) {
3072 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
3073 return createCXString(ND->getNameAsString());
3074 return createCXString("");
3075 }
3076 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3077 return createCXString(E->getName().getAsString());
3078 OverloadedTemplateStorage *Ovl
3079 = Storage.get<OverloadedTemplateStorage*>();
3080 if (Ovl->size() == 0)
3081 return createCXString("");
3082 return createCXString((*Ovl->begin())->getNameAsString());
3083 }
3084
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003085 default:
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003086 return createCXString("<not implemented>");
Steve Naroff80a766b2009-09-02 18:26:48 +00003087 }
3088 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003089
3090 if (clang_isExpression(C.kind)) {
3091 Decl *D = getDeclFromExpr(getCursorExpr(C));
3092 if (D)
Douglas Gregordd969c82010-01-20 21:45:58 +00003093 return getDeclSpelling(D);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003094 return createCXString("");
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003095 }
3096
Douglas Gregora93ab662010-09-10 00:22:18 +00003097 if (clang_isStatement(C.kind)) {
3098 Stmt *S = getCursorStmt(C);
3099 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003100 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00003101
3102 return createCXString("");
3103 }
3104
Douglas Gregor065f8d12010-03-18 17:52:52 +00003105 if (C.kind == CXCursor_MacroInstantiation)
3106 return createCXString(getCursorMacroInstantiation(C)->getName()
3107 ->getNameStart());
3108
Douglas Gregor06d6d322010-03-18 18:04:21 +00003109 if (C.kind == CXCursor_MacroDefinition)
3110 return createCXString(getCursorMacroDefinition(C)->getName()
3111 ->getNameStart());
3112
Douglas Gregor796d76a2010-10-20 22:00:55 +00003113 if (C.kind == CXCursor_InclusionDirective)
3114 return createCXString(getCursorInclusionDirective(C)->getFileName());
3115
Douglas Gregor5bce76c2010-01-25 16:56:17 +00003116 if (clang_isDeclaration(C.kind))
3117 return getDeclSpelling(getCursorDecl(C));
Ted Kremenek29004672010-02-17 00:41:32 +00003118
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003119 return createCXString("");
Steve Naroff80a766b2009-09-02 18:26:48 +00003120}
3121
Douglas Gregor97c75712010-10-02 22:49:11 +00003122CXString clang_getCursorDisplayName(CXCursor C) {
3123 if (!clang_isDeclaration(C.kind))
3124 return clang_getCursorSpelling(C);
3125
3126 Decl *D = getCursorDecl(C);
3127 if (!D)
3128 return createCXString("");
3129
3130 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3131 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3132 D = FunTmpl->getTemplatedDecl();
3133
3134 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3135 llvm::SmallString<64> Str;
3136 llvm::raw_svector_ostream OS(Str);
3137 OS << Function->getNameAsString();
3138 if (Function->getPrimaryTemplate())
3139 OS << "<>";
3140 OS << "(";
3141 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3142 if (I)
3143 OS << ", ";
3144 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3145 }
3146
3147 if (Function->isVariadic()) {
3148 if (Function->getNumParams())
3149 OS << ", ";
3150 OS << "...";
3151 }
3152 OS << ")";
3153 return createCXString(OS.str());
3154 }
3155
3156 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3157 llvm::SmallString<64> Str;
3158 llvm::raw_svector_ostream OS(Str);
3159 OS << ClassTemplate->getNameAsString();
3160 OS << "<";
3161 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3162 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3163 if (I)
3164 OS << ", ";
3165
3166 NamedDecl *Param = Params->getParam(I);
3167 if (Param->getIdentifier()) {
3168 OS << Param->getIdentifier()->getName();
3169 continue;
3170 }
3171
3172 // There is no parameter name, which makes this tricky. Try to come up
3173 // with something useful that isn't too long.
3174 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3175 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3176 else if (NonTypeTemplateParmDecl *NTTP
3177 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3178 OS << NTTP->getType().getAsString(Policy);
3179 else
3180 OS << "template<...> class";
3181 }
3182
3183 OS << ">";
3184 return createCXString(OS.str());
3185 }
3186
3187 if (ClassTemplateSpecializationDecl *ClassSpec
3188 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3189 // If the type was explicitly written, use that.
3190 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3191 return createCXString(TSInfo->getType().getAsString(Policy));
3192
3193 llvm::SmallString<64> Str;
3194 llvm::raw_svector_ostream OS(Str);
3195 OS << ClassSpec->getNameAsString();
3196 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor1ccc8412010-11-07 23:05:16 +00003197 ClassSpec->getTemplateArgs().data(),
3198 ClassSpec->getTemplateArgs().size(),
Douglas Gregor97c75712010-10-02 22:49:11 +00003199 Policy);
3200 return createCXString(OS.str());
3201 }
3202
3203 return clang_getCursorSpelling(C);
3204}
3205
Ted Kremenek29004672010-02-17 00:41:32 +00003206CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff1054e602009-08-31 00:59:03 +00003207 switch (Kind) {
Ted Kremenek29004672010-02-17 00:41:32 +00003208 case CXCursor_FunctionDecl:
3209 return createCXString("FunctionDecl");
3210 case CXCursor_TypedefDecl:
3211 return createCXString("TypedefDecl");
3212 case CXCursor_EnumDecl:
3213 return createCXString("EnumDecl");
3214 case CXCursor_EnumConstantDecl:
3215 return createCXString("EnumConstantDecl");
3216 case CXCursor_StructDecl:
3217 return createCXString("StructDecl");
3218 case CXCursor_UnionDecl:
3219 return createCXString("UnionDecl");
3220 case CXCursor_ClassDecl:
3221 return createCXString("ClassDecl");
3222 case CXCursor_FieldDecl:
3223 return createCXString("FieldDecl");
3224 case CXCursor_VarDecl:
3225 return createCXString("VarDecl");
3226 case CXCursor_ParmDecl:
3227 return createCXString("ParmDecl");
3228 case CXCursor_ObjCInterfaceDecl:
3229 return createCXString("ObjCInterfaceDecl");
3230 case CXCursor_ObjCCategoryDecl:
3231 return createCXString("ObjCCategoryDecl");
3232 case CXCursor_ObjCProtocolDecl:
3233 return createCXString("ObjCProtocolDecl");
3234 case CXCursor_ObjCPropertyDecl:
3235 return createCXString("ObjCPropertyDecl");
3236 case CXCursor_ObjCIvarDecl:
3237 return createCXString("ObjCIvarDecl");
3238 case CXCursor_ObjCInstanceMethodDecl:
3239 return createCXString("ObjCInstanceMethodDecl");
3240 case CXCursor_ObjCClassMethodDecl:
3241 return createCXString("ObjCClassMethodDecl");
3242 case CXCursor_ObjCImplementationDecl:
3243 return createCXString("ObjCImplementationDecl");
3244 case CXCursor_ObjCCategoryImplDecl:
3245 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek225b8e32010-04-13 23:39:06 +00003246 case CXCursor_CXXMethod:
3247 return createCXString("CXXMethod");
Ted Kremenek29004672010-02-17 00:41:32 +00003248 case CXCursor_UnexposedDecl:
3249 return createCXString("UnexposedDecl");
3250 case CXCursor_ObjCSuperClassRef:
3251 return createCXString("ObjCSuperClassRef");
3252 case CXCursor_ObjCProtocolRef:
3253 return createCXString("ObjCProtocolRef");
3254 case CXCursor_ObjCClassRef:
3255 return createCXString("ObjCClassRef");
3256 case CXCursor_TypeRef:
3257 return createCXString("TypeRef");
Douglas Gregora23e8f72010-08-31 20:37:03 +00003258 case CXCursor_TemplateRef:
3259 return createCXString("TemplateRef");
Douglas Gregora89314e2010-08-31 23:48:11 +00003260 case CXCursor_NamespaceRef:
3261 return createCXString("NamespaceRef");
Douglas Gregorf3af3112010-09-09 21:42:20 +00003262 case CXCursor_MemberRef:
3263 return createCXString("MemberRef");
Douglas Gregora93ab662010-09-10 00:22:18 +00003264 case CXCursor_LabelRef:
3265 return createCXString("LabelRef");
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003266 case CXCursor_OverloadedDeclRef:
3267 return createCXString("OverloadedDeclRef");
Ted Kremenek29004672010-02-17 00:41:32 +00003268 case CXCursor_UnexposedExpr:
3269 return createCXString("UnexposedExpr");
Ted Kremenek33b9a422010-04-11 21:47:37 +00003270 case CXCursor_BlockExpr:
3271 return createCXString("BlockExpr");
Ted Kremenek29004672010-02-17 00:41:32 +00003272 case CXCursor_DeclRefExpr:
3273 return createCXString("DeclRefExpr");
3274 case CXCursor_MemberRefExpr:
3275 return createCXString("MemberRefExpr");
3276 case CXCursor_CallExpr:
3277 return createCXString("CallExpr");
3278 case CXCursor_ObjCMessageExpr:
3279 return createCXString("ObjCMessageExpr");
3280 case CXCursor_UnexposedStmt:
3281 return createCXString("UnexposedStmt");
Douglas Gregora93ab662010-09-10 00:22:18 +00003282 case CXCursor_LabelStmt:
3283 return createCXString("LabelStmt");
Ted Kremenek29004672010-02-17 00:41:32 +00003284 case CXCursor_InvalidFile:
3285 return createCXString("InvalidFile");
Ted Kremenek00da3b92010-03-19 20:39:05 +00003286 case CXCursor_InvalidCode:
3287 return createCXString("InvalidCode");
Ted Kremenek29004672010-02-17 00:41:32 +00003288 case CXCursor_NoDeclFound:
3289 return createCXString("NoDeclFound");
3290 case CXCursor_NotImplemented:
3291 return createCXString("NotImplemented");
3292 case CXCursor_TranslationUnit:
3293 return createCXString("TranslationUnit");
Ted Kremenekbff31432010-02-18 03:09:07 +00003294 case CXCursor_UnexposedAttr:
3295 return createCXString("UnexposedAttr");
3296 case CXCursor_IBActionAttr:
3297 return createCXString("attribute(ibaction)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003298 case CXCursor_IBOutletAttr:
3299 return createCXString("attribute(iboutlet)");
Ted Kremenek26bde772010-05-19 17:38:06 +00003300 case CXCursor_IBOutletCollectionAttr:
3301 return createCXString("attribute(iboutletcollection)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003302 case CXCursor_PreprocessingDirective:
3303 return createCXString("preprocessing directive");
Douglas Gregor06d6d322010-03-18 18:04:21 +00003304 case CXCursor_MacroDefinition:
3305 return createCXString("macro definition");
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003306 case CXCursor_MacroInstantiation:
3307 return createCXString("macro instantiation");
Douglas Gregor796d76a2010-10-20 22:00:55 +00003308 case CXCursor_InclusionDirective:
3309 return createCXString("inclusion directive");
Ted Kremenekbd67fb22010-05-06 23:38:21 +00003310 case CXCursor_Namespace:
3311 return createCXString("Namespace");
Ted Kremenekb80cba52010-05-07 01:04:29 +00003312 case CXCursor_LinkageSpec:
3313 return createCXString("LinkageSpec");
Ted Kremenekae9e2212010-08-27 21:34:58 +00003314 case CXCursor_CXXBaseSpecifier:
3315 return createCXString("C++ base class specifier");
Douglas Gregor12bca222010-08-31 14:41:23 +00003316 case CXCursor_Constructor:
3317 return createCXString("CXXConstructor");
3318 case CXCursor_Destructor:
3319 return createCXString("CXXDestructor");
3320 case CXCursor_ConversionFunction:
3321 return createCXString("CXXConversion");
Douglas Gregor713602b2010-08-31 17:01:39 +00003322 case CXCursor_TemplateTypeParameter:
3323 return createCXString("TemplateTypeParameter");
3324 case CXCursor_NonTypeTemplateParameter:
3325 return createCXString("NonTypeTemplateParameter");
3326 case CXCursor_TemplateTemplateParameter:
3327 return createCXString("TemplateTemplateParameter");
3328 case CXCursor_FunctionTemplate:
3329 return createCXString("FunctionTemplate");
Douglas Gregor1fbaeb12010-08-31 19:02:00 +00003330 case CXCursor_ClassTemplate:
3331 return createCXString("ClassTemplate");
Douglas Gregorf96abb22010-08-31 19:31:58 +00003332 case CXCursor_ClassTemplatePartialSpecialization:
3333 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregora89314e2010-08-31 23:48:11 +00003334 case CXCursor_NamespaceAlias:
3335 return createCXString("NamespaceAlias");
Douglas Gregor01a430132010-09-01 03:07:18 +00003336 case CXCursor_UsingDirective:
3337 return createCXString("UsingDirective");
Douglas Gregora9aa29c2010-09-01 19:52:22 +00003338 case CXCursor_UsingDeclaration:
3339 return createCXString("UsingDeclaration");
Steve Naroff1054e602009-08-31 00:59:03 +00003340 }
Ted Kremenek29004672010-02-17 00:41:32 +00003341
Ted Kremenek4ba52632010-01-16 02:02:09 +00003342 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremenek91554282010-11-16 08:15:36 +00003343 return createCXString((const char*) 0);
Steve Naroffd5e8e862009-08-27 19:51:58 +00003344}
Steve Naroff1054e602009-08-31 00:59:03 +00003345
Ted Kremenek29004672010-02-17 00:41:32 +00003346enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3347 CXCursor parent,
Douglas Gregor562c1f92010-01-22 19:49:59 +00003348 CXClientData client_data) {
3349 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor16443fd2010-11-05 21:11:19 +00003350
3351 // If our current best cursor is the construction of a temporary object,
3352 // don't replace that cursor with a type reference, because we want
3353 // clang_getCursor() to point at the constructor.
3354 if (clang_isExpression(BestCursor->kind) &&
3355 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3356 cursor.kind == CXCursor_TypeRef)
3357 return CXChildVisit_Recurse;
3358
Douglas Gregor3046b4d2010-12-10 07:23:11 +00003359 // Don't override a preprocessing cursor with another preprocessing
3360 // cursor; we want the outermost preprocessing cursor.
3361 if (clang_isPreprocessing(cursor.kind) &&
3362 clang_isPreprocessing(BestCursor->kind))
3363 return CXChildVisit_Recurse;
3364
Douglas Gregor562c1f92010-01-22 19:49:59 +00003365 *BestCursor = cursor;
3366 return CXChildVisit_Recurse;
3367}
Ted Kremenek29004672010-02-17 00:41:32 +00003368
Douglas Gregor816fd362010-01-22 21:44:22 +00003369CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3370 if (!TU)
Ted Kremeneke34cbde2010-01-14 01:51:23 +00003371 return clang_getNullCursor();
Ted Kremenek29004672010-02-17 00:41:32 +00003372
Ted Kremenek91554282010-11-16 08:15:36 +00003373 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00003374 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3375
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003376 // Translate the given source location to make it point at the beginning of
3377 // the token under the cursor.
Ted Kremenek97a45372010-01-25 22:34:44 +00003378 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremenek1e589f22010-07-29 00:52:07 +00003379
3380 // Guard against an invalid SourceLocation, or we may assert in one
3381 // of the following calls.
3382 if (SLoc.isInvalid())
3383 return clang_getNullCursor();
3384
Douglas Gregor15417cf2010-11-03 00:35:38 +00003385 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003386 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3387 CXXUnit->getASTContext().getLangOptions());
3388
Douglas Gregor562c1f92010-01-22 19:49:59 +00003389 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3390 if (SLoc.isValid()) {
Douglas Gregor562c1f92010-01-22 19:49:59 +00003391 // FIXME: Would be great to have a "hint" cursor, then walk from that
3392 // hint cursor upward until we find a cursor whose source range encloses
3393 // the region of interest, rather than starting from the translation unit.
Ted Kremenek91554282010-11-16 08:15:36 +00003394 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3395 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregorc2b97992011-03-16 23:23:30 +00003396 Decl::MaxPCHLevel, true, SourceLocation(SLoc));
Douglas Gregor562c1f92010-01-22 19:49:59 +00003397 CursorVis.VisitChildren(Parent);
Steve Naroff54f22fb2009-09-15 20:25:34 +00003398 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003399
3400 if (Logging) {
3401 CXFile SearchFile;
3402 unsigned SearchLine, SearchColumn;
3403 CXFile ResultFile;
3404 unsigned ResultLine, ResultColumn;
Douglas Gregor29ee4222010-11-17 17:14:07 +00003405 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3406 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor15417cf2010-11-03 00:35:38 +00003407 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3408
3409 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3410 0);
3411 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3412 &ResultColumn, 0);
3413 SearchFileName = clang_getFileName(SearchFile);
3414 ResultFileName = clang_getFileName(ResultFile);
3415 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003416 USR = clang_getCursorUSR(Result);
3417 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor15417cf2010-11-03 00:35:38 +00003418 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3419 clang_getCString(KindSpelling),
Douglas Gregor29ee4222010-11-17 17:14:07 +00003420 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3421 clang_getCString(USR), IsDef);
Douglas Gregor15417cf2010-11-03 00:35:38 +00003422 clang_disposeString(SearchFileName);
3423 clang_disposeString(ResultFileName);
3424 clang_disposeString(KindSpelling);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003425 clang_disposeString(USR);
Douglas Gregor4a5bd5f2010-12-10 01:45:00 +00003426
3427 CXCursor Definition = clang_getCursorDefinition(Result);
3428 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3429 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3430 CXString DefinitionKindSpelling
3431 = clang_getCursorKindSpelling(Definition.kind);
3432 CXFile DefinitionFile;
3433 unsigned DefinitionLine, DefinitionColumn;
3434 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3435 &DefinitionLine, &DefinitionColumn, 0);
3436 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3437 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3438 clang_getCString(DefinitionKindSpelling),
3439 clang_getCString(DefinitionFileName),
3440 DefinitionLine, DefinitionColumn);
3441 clang_disposeString(DefinitionFileName);
3442 clang_disposeString(DefinitionKindSpelling);
3443 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003444 }
3445
Ted Kremenek29004672010-02-17 00:41:32 +00003446 return Result;
Steve Naroffd5e8e862009-08-27 19:51:58 +00003447}
3448
Ted Kremeneke05d7802009-11-17 19:28:59 +00003449CXCursor clang_getNullCursor(void) {
Douglas Gregor58552bc2010-01-20 23:34:41 +00003450 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremeneke05d7802009-11-17 19:28:59 +00003451}
3452
3453unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00003454 return X == Y;
Ted Kremeneke05d7802009-11-17 19:28:59 +00003455}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00003456
Douglas Gregor06a3f302010-11-20 00:09:34 +00003457unsigned clang_hashCursor(CXCursor C) {
3458 unsigned Index = 0;
3459 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3460 Index = 1;
3461
3462 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3463 std::make_pair(C.kind, C.data[Index]));
3464}
3465
Daniel Dunbar079203f2009-12-01 03:14:51 +00003466unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff54f22fb2009-09-15 20:25:34 +00003467 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3468}
3469
Daniel Dunbar079203f2009-12-01 03:14:51 +00003470unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff1054e602009-08-31 00:59:03 +00003471 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3472}
Steve Naroff772c1a42009-08-31 14:26:51 +00003473
Daniel Dunbar079203f2009-12-01 03:14:51 +00003474unsigned clang_isReference(enum CXCursorKind K) {
Steve Naroff80a766b2009-09-02 18:26:48 +00003475 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3476}
3477
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003478unsigned clang_isExpression(enum CXCursorKind K) {
3479 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3480}
3481
3482unsigned clang_isStatement(enum CXCursorKind K) {
3483 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3484}
3485
Douglas Gregord2fc7272010-01-20 00:23:15 +00003486unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3487 return K == CXCursor_TranslationUnit;
3488}
3489
Douglas Gregor92a524f2010-03-18 00:42:48 +00003490unsigned clang_isPreprocessing(enum CXCursorKind K) {
3491 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3492}
3493
Ted Kremenekff9021b2010-03-08 21:17:29 +00003494unsigned clang_isUnexposed(enum CXCursorKind K) {
3495 switch (K) {
3496 case CXCursor_UnexposedDecl:
3497 case CXCursor_UnexposedExpr:
3498 case CXCursor_UnexposedStmt:
3499 case CXCursor_UnexposedAttr:
3500 return true;
3501 default:
3502 return false;
3503 }
3504}
3505
Daniel Dunbar079203f2009-12-01 03:14:51 +00003506CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroffef9618b2009-09-04 15:44:05 +00003507 return C.kind;
3508}
3509
Douglas Gregor66a58812010-01-18 22:46:11 +00003510CXSourceLocation clang_getCursorLocation(CXCursor C) {
3511 if (clang_isReference(C.kind)) {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003512 switch (C.kind) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00003513 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003514 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3515 = getCursorObjCSuperClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003516 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003517 }
3518
Ted Kremenekf441baf2010-02-17 00:41:40 +00003519 case CXCursor_ObjCProtocolRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003520 std::pair<ObjCProtocolDecl *, SourceLocation> P
3521 = getCursorObjCProtocolRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003522 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003523 }
3524
Ted Kremenekf441baf2010-02-17 00:41:40 +00003525 case CXCursor_ObjCClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003526 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3527 = getCursorObjCClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003528 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003529 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003530
Ted Kremenekf441baf2010-02-17 00:41:40 +00003531 case CXCursor_TypeRef: {
Douglas Gregor93f89952010-01-21 16:28:34 +00003532 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003533 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor93f89952010-01-21 16:28:34 +00003534 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00003535
3536 case CXCursor_TemplateRef: {
3537 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3538 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3539 }
3540
Douglas Gregora89314e2010-08-31 23:48:11 +00003541 case CXCursor_NamespaceRef: {
3542 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3543 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3544 }
3545
Douglas Gregorf3af3112010-09-09 21:42:20 +00003546 case CXCursor_MemberRef: {
3547 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3548 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3549 }
3550
Ted Kremenekae9e2212010-08-27 21:34:58 +00003551 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor3478c752010-10-02 19:51:13 +00003552 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3553 if (!BaseSpec)
3554 return clang_getNullLocation();
3555
3556 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3557 return cxloc::translateSourceLocation(getCursorContext(C),
3558 TSInfo->getTypeLoc().getBeginLoc());
3559
3560 return cxloc::translateSourceLocation(getCursorContext(C),
3561 BaseSpec->getSourceRange().getBegin());
Ted Kremenekae9e2212010-08-27 21:34:58 +00003562 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003563
Douglas Gregora93ab662010-09-10 00:22:18 +00003564 case CXCursor_LabelRef: {
3565 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3566 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3567 }
3568
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003569 case CXCursor_OverloadedDeclRef:
3570 return cxloc::translateSourceLocation(getCursorContext(C),
3571 getCursorOverloadedDeclRef(C).second);
3572
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003573 default:
3574 // FIXME: Need a way to enumerate all non-reference cases.
3575 llvm_unreachable("Missed a reference kind");
3576 }
Douglas Gregor66a58812010-01-18 22:46:11 +00003577 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003578
3579 if (clang_isExpression(C.kind))
Ted Kremenekf441baf2010-02-17 00:41:40 +00003580 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003581 getLocationFromExpr(getCursorExpr(C)));
3582
Douglas Gregora93ab662010-09-10 00:22:18 +00003583 if (clang_isStatement(C.kind))
3584 return cxloc::translateSourceLocation(getCursorContext(C),
3585 getCursorStmt(C)->getLocStart());
3586
Douglas Gregor92a524f2010-03-18 00:42:48 +00003587 if (C.kind == CXCursor_PreprocessingDirective) {
3588 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3589 return cxloc::translateSourceLocation(getCursorContext(C), L);
3590 }
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003591
3592 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor065f8d12010-03-18 17:52:52 +00003593 SourceLocation L
3594 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003595 return cxloc::translateSourceLocation(getCursorContext(C), L);
3596 }
Douglas Gregor06d6d322010-03-18 18:04:21 +00003597
3598 if (C.kind == CXCursor_MacroDefinition) {
3599 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3600 return cxloc::translateSourceLocation(getCursorContext(C), L);
3601 }
Douglas Gregor796d76a2010-10-20 22:00:55 +00003602
3603 if (C.kind == CXCursor_InclusionDirective) {
3604 SourceLocation L
3605 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3606 return cxloc::translateSourceLocation(getCursorContext(C), L);
3607 }
3608
Ted Kremenek8278a322010-05-12 06:16:13 +00003609 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003610 return clang_getNullLocation();
Douglas Gregor66a58812010-01-18 22:46:11 +00003611
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003612 Decl *D = getCursorDecl(C);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003613 SourceLocation Loc = D->getLocation();
3614 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3615 Loc = Class->getClassLoc();
Ted Kremenek818e5c12010-11-01 23:26:51 +00003616 // FIXME: Multiple variables declared in a single declaration
3617 // currently lack the information needed to correctly determine their
3618 // ranges when accounting for the type-specifier. We use context
3619 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3620 // and if so, whether it is the first decl.
3621 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3622 if (!cxcursor::isFirstInDeclGroup(C))
3623 Loc = VD->getLocation();
3624 }
3625
Douglas Gregor7bf6b8a2010-03-22 15:53:50 +00003626 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor66a58812010-01-18 22:46:11 +00003627}
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003628
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003629} // end extern "C"
3630
3631static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003632 if (clang_isReference(C.kind)) {
3633 switch (C.kind) {
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003634 case CXCursor_ObjCSuperClassRef:
3635 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003636
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003637 case CXCursor_ObjCProtocolRef:
3638 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003639
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003640 case CXCursor_ObjCClassRef:
3641 return getCursorObjCClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003642
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003643 case CXCursor_TypeRef:
3644 return getCursorTypeRef(C).second;
Douglas Gregora23e8f72010-08-31 20:37:03 +00003645
3646 case CXCursor_TemplateRef:
3647 return getCursorTemplateRef(C).second;
3648
Douglas Gregora89314e2010-08-31 23:48:11 +00003649 case CXCursor_NamespaceRef:
3650 return getCursorNamespaceRef(C).second;
Douglas Gregorf3af3112010-09-09 21:42:20 +00003651
3652 case CXCursor_MemberRef:
3653 return getCursorMemberRef(C).second;
3654
Ted Kremenekae9e2212010-08-27 21:34:58 +00003655 case CXCursor_CXXBaseSpecifier:
Douglas Gregor3478c752010-10-02 19:51:13 +00003656 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor93f89952010-01-21 16:28:34 +00003657
Douglas Gregora93ab662010-09-10 00:22:18 +00003658 case CXCursor_LabelRef:
3659 return getCursorLabelRef(C).second;
3660
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003661 case CXCursor_OverloadedDeclRef:
3662 return getCursorOverloadedDeclRef(C).second;
3663
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003664 default:
3665 // FIXME: Need a way to enumerate all non-reference cases.
3666 llvm_unreachable("Missed a reference kind");
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003667 }
3668 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003669
3670 if (clang_isExpression(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003671 return getCursorExpr(C)->getSourceRange();
Douglas Gregor562c1f92010-01-22 19:49:59 +00003672
3673 if (clang_isStatement(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003674 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003675
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003676 if (C.kind == CXCursor_PreprocessingDirective)
3677 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003678
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003679 if (C.kind == CXCursor_MacroInstantiation)
3680 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor06d6d322010-03-18 18:04:21 +00003681
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003682 if (C.kind == CXCursor_MacroDefinition)
3683 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregor796d76a2010-10-20 22:00:55 +00003684
3685 if (C.kind == CXCursor_InclusionDirective)
3686 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3687
Ted Kremenek818e5c12010-11-01 23:26:51 +00003688 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3689 Decl *D = cxcursor::getCursorDecl(C);
3690 SourceRange R = D->getSourceRange();
3691 // FIXME: Multiple variables declared in a single declaration
3692 // currently lack the information needed to correctly determine their
3693 // ranges when accounting for the type-specifier. We use context
3694 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3695 // and if so, whether it is the first decl.
3696 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3697 if (!cxcursor::isFirstInDeclGroup(C))
3698 R.setBegin(VD->getLocation());
3699 }
3700 return R;
3701 }
Douglas Gregor29ee4222010-11-17 17:14:07 +00003702 return SourceRange();
3703}
3704
3705/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3706/// the decl-specifier-seq for declarations.
3707static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3708 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3709 Decl *D = cxcursor::getCursorDecl(C);
3710 SourceRange R = D->getSourceRange();
Douglas Gregor29ee4222010-11-17 17:14:07 +00003711
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00003712 // Adjust the start of the location for declarations preceded by
3713 // declaration specifiers.
3714 SourceLocation StartLoc;
3715 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3716 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3717 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3718 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3719 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3720 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3721 }
3722
3723 if (StartLoc.isValid() && R.getBegin().isValid() &&
3724 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3725 R.setBegin(StartLoc);
3726
3727 // FIXME: Multiple variables declared in a single declaration
3728 // currently lack the information needed to correctly determine their
3729 // ranges when accounting for the type-specifier. We use context
3730 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3731 // and if so, whether it is the first decl.
3732 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3733 if (!cxcursor::isFirstInDeclGroup(C))
3734 R.setBegin(VD->getLocation());
Douglas Gregor29ee4222010-11-17 17:14:07 +00003735 }
3736
3737 return R;
3738 }
3739
3740 return getRawCursorExtent(C);
3741}
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003742
3743extern "C" {
3744
3745CXSourceRange clang_getCursorExtent(CXCursor C) {
3746 SourceRange R = getRawCursorExtent(C);
3747 if (R.isInvalid())
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003748 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003749
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003750 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003751}
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003752
3753CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003754 if (clang_isInvalid(C.kind))
3755 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003756
Ted Kremenek91554282010-11-16 08:15:36 +00003757 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003758 if (clang_isDeclaration(C.kind)) {
3759 Decl *D = getCursorDecl(C);
3760 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003761 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003762 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003763 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003764 if (ObjCForwardProtocolDecl *Protocols
3765 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003766 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00003767 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3768 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3769 return MakeCXCursor(Property, tu);
3770
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003771 return C;
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003772 }
3773
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003774 if (clang_isExpression(C.kind)) {
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003775 Expr *E = getCursorExpr(C);
3776 Decl *D = getDeclFromExpr(E);
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003777 if (D)
Ted Kremenek91554282010-11-16 08:15:36 +00003778 return MakeCXCursor(D, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003779
3780 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremenek91554282010-11-16 08:15:36 +00003781 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003782
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003783 return clang_getNullCursor();
3784 }
3785
Douglas Gregora93ab662010-09-10 00:22:18 +00003786 if (clang_isStatement(C.kind)) {
3787 Stmt *S = getCursorStmt(C);
3788 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Ted Kremenek6f7008d2011-03-15 23:47:49 +00003789 if (LabelDecl *label = Goto->getLabel())
3790 if (LabelStmt *labelS = label->getStmt())
3791 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003792
3793 return clang_getNullCursor();
3794 }
3795
Douglas Gregor78ae2482010-03-18 18:23:03 +00003796 if (C.kind == CXCursor_MacroInstantiation) {
3797 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003798 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregor78ae2482010-03-18 18:23:03 +00003799 }
3800
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003801 if (!clang_isReference(C.kind))
3802 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003803
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003804 switch (C.kind) {
3805 case CXCursor_ObjCSuperClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003806 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003807
3808 case CXCursor_ObjCProtocolRef: {
Ted Kremenek91554282010-11-16 08:15:36 +00003809 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003810
3811 case CXCursor_ObjCClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003812 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor93f89952010-01-21 16:28:34 +00003813
Ted Kremenekf441baf2010-02-17 00:41:40 +00003814 case CXCursor_TypeRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003815 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003816
3817 case CXCursor_TemplateRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003818 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003819
Douglas Gregora89314e2010-08-31 23:48:11 +00003820 case CXCursor_NamespaceRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003821 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregora89314e2010-08-31 23:48:11 +00003822
Douglas Gregorf3af3112010-09-09 21:42:20 +00003823 case CXCursor_MemberRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003824 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregorf3af3112010-09-09 21:42:20 +00003825
Ted Kremenekae9e2212010-08-27 21:34:58 +00003826 case CXCursor_CXXBaseSpecifier: {
3827 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3828 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremenek91554282010-11-16 08:15:36 +00003829 tu ));
Ted Kremenekae9e2212010-08-27 21:34:58 +00003830 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003831
Douglas Gregora93ab662010-09-10 00:22:18 +00003832 case CXCursor_LabelRef:
3833 // FIXME: We end up faking the "parent" declaration here because we
3834 // don't want to make CXCursor larger.
3835 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremenek91554282010-11-16 08:15:36 +00003836 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3837 .getTranslationUnitDecl(),
3838 tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003839
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003840 case CXCursor_OverloadedDeclRef:
3841 return C;
3842
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003843 default:
3844 // We would prefer to enumerate all non-reference cursor kinds here.
3845 llvm_unreachable("Unhandled reference cursor kind");
3846 break;
3847 }
3848 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003849
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003850 return clang_getNullCursor();
3851}
3852
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003853CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003854 if (clang_isInvalid(C.kind))
3855 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003856
Ted Kremenek91554282010-11-16 08:15:36 +00003857 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003858
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003859 bool WasReference = false;
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003860 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003861 C = clang_getCursorReferenced(C);
3862 WasReference = true;
3863 }
3864
Douglas Gregor78ae2482010-03-18 18:23:03 +00003865 if (C.kind == CXCursor_MacroInstantiation)
3866 return clang_getCursorReferenced(C);
3867
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003868 if (!clang_isDeclaration(C.kind))
3869 return clang_getNullCursor();
3870
3871 Decl *D = getCursorDecl(C);
3872 if (!D)
3873 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003874
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003875 switch (D->getKind()) {
3876 // Declaration kinds that don't really separate the notions of
3877 // declaration and definition.
3878 case Decl::Namespace:
3879 case Decl::Typedef:
3880 case Decl::TemplateTypeParm:
3881 case Decl::EnumConstant:
3882 case Decl::Field:
Benjamin Kramer39593702010-11-21 14:11:41 +00003883 case Decl::IndirectField:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003884 case Decl::ObjCIvar:
3885 case Decl::ObjCAtDefsField:
3886 case Decl::ImplicitParam:
3887 case Decl::ParmVar:
3888 case Decl::NonTypeTemplateParm:
3889 case Decl::TemplateTemplateParm:
3890 case Decl::ObjCCategoryImpl:
3891 case Decl::ObjCImplementation:
Abramo Bagnarad7340582010-06-05 05:09:32 +00003892 case Decl::AccessSpec:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003893 case Decl::LinkageSpec:
3894 case Decl::ObjCPropertyImpl:
3895 case Decl::FileScopeAsm:
3896 case Decl::StaticAssert:
3897 case Decl::Block:
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003898 case Decl::Label: // FIXME: Is this right??
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003899 return C;
3900
3901 // Declaration kinds that don't make any sense here, but are
3902 // nonetheless harmless.
3903 case Decl::TranslationUnit:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003904 break;
3905
3906 // Declaration kinds for which the definition is not resolvable.
3907 case Decl::UnresolvedUsingTypename:
3908 case Decl::UnresolvedUsingValue:
3909 break;
3910
3911 case Decl::UsingDirective:
Douglas Gregorfed36b12010-01-20 23:57:43 +00003912 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremenek91554282010-11-16 08:15:36 +00003913 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003914
3915 case Decl::NamespaceAlias:
Ted Kremenek91554282010-11-16 08:15:36 +00003916 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003917
3918 case Decl::Enum:
3919 case Decl::Record:
3920 case Decl::CXXRecord:
3921 case Decl::ClassTemplateSpecialization:
3922 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003923 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003924 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003925 return clang_getNullCursor();
3926
3927 case Decl::Function:
3928 case Decl::CXXMethod:
3929 case Decl::CXXConstructor:
3930 case Decl::CXXDestructor:
3931 case Decl::CXXConversion: {
3932 const FunctionDecl *Def = 0;
3933 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003934 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003935 return clang_getNullCursor();
3936 }
3937
3938 case Decl::Var: {
Sebastian Redl5ca79842010-02-01 20:16:42 +00003939 // Ask the variable if it has a definition.
3940 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003941 return MakeCXCursor(Def, TU);
Sebastian Redl5ca79842010-02-01 20:16:42 +00003942 return clang_getNullCursor();
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003943 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003944
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003945 case Decl::FunctionTemplate: {
3946 const FunctionDecl *Def = 0;
3947 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003948 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003949 return clang_getNullCursor();
3950 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003951
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003952 case Decl::ClassTemplate: {
3953 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003954 ->getDefinition())
Douglas Gregora23e8f72010-08-31 20:37:03 +00003955 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremenek91554282010-11-16 08:15:36 +00003956 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003957 return clang_getNullCursor();
3958 }
3959
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003960 case Decl::Using:
3961 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00003962 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003963
3964 case Decl::UsingShadow:
3965 return clang_getCursorDefinition(
Ted Kremenekf441baf2010-02-17 00:41:40 +00003966 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremenek91554282010-11-16 08:15:36 +00003967 TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003968
3969 case Decl::ObjCMethod: {
3970 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3971 if (Method->isThisDeclarationADefinition())
3972 return C;
3973
3974 // Dig out the method definition in the associated
3975 // @implementation, if we have it.
3976 // FIXME: The ASTs should make finding the definition easier.
3977 if (ObjCInterfaceDecl *Class
3978 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3979 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3980 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3981 Method->isInstanceMethod()))
3982 if (Def->isThisDeclarationADefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003983 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003984
3985 return clang_getNullCursor();
3986 }
3987
3988 case Decl::ObjCCategory:
3989 if (ObjCCategoryImplDecl *Impl
3990 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00003991 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003992 return clang_getNullCursor();
3993
3994 case Decl::ObjCProtocol:
3995 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3996 return C;
3997 return clang_getNullCursor();
3998
3999 case Decl::ObjCInterface:
4000 // There are two notions of a "definition" for an Objective-C
4001 // class: the interface and its implementation. When we resolved a
4002 // reference to an Objective-C class, produce the @interface as
4003 // the definition; when we were provided with the interface,
4004 // produce the @implementation as the definition.
4005 if (WasReference) {
4006 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4007 return C;
4008 } else if (ObjCImplementationDecl *Impl
4009 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00004010 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004011 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004012
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004013 case Decl::ObjCProperty:
4014 // FIXME: We don't really know where to find the
4015 // ObjCPropertyImplDecls that implement this property.
4016 return clang_getNullCursor();
4017
4018 case Decl::ObjCCompatibleAlias:
4019 if (ObjCInterfaceDecl *Class
4020 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4021 if (!Class->isForwardDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004022 return MakeCXCursor(Class, TU);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004023
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004024 return clang_getNullCursor();
4025
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004026 case Decl::ObjCForwardProtocol:
4027 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00004028 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004029
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004030 case Decl::ObjCClass:
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00004031 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremenek91554282010-11-16 08:15:36 +00004032 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004033
4034 case Decl::Friend:
4035 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004036 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004037 return clang_getNullCursor();
4038
4039 case Decl::FriendTemplate:
4040 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00004041 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00004042 return clang_getNullCursor();
4043 }
4044
4045 return clang_getNullCursor();
4046}
4047
4048unsigned clang_isCursorDefinition(CXCursor C) {
4049 if (!clang_isDeclaration(C.kind))
4050 return 0;
4051
4052 return clang_getCursorDefinition(C) == C;
4053}
4054
Douglas Gregorfec4dc92010-11-19 23:44:15 +00004055CXCursor clang_getCanonicalCursor(CXCursor C) {
4056 if (!clang_isDeclaration(C.kind))
4057 return C;
4058
4059 if (Decl *D = getCursorDecl(C))
4060 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4061
4062 return C;
4063}
4064
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004065unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregorae185302010-09-16 13:54:00 +00004066 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004067 return 0;
4068
4069 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4070 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4071 return E->getNumDecls();
4072
4073 if (OverloadedTemplateStorage *S
4074 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4075 return S->size();
4076
4077 Decl *D = Storage.get<Decl*>();
4078 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis2703beb2010-11-10 05:40:41 +00004079 return Using->shadow_size();
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004080 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4081 return Classes->size();
4082 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4083 return Protocols->protocol_size();
4084
4085 return 0;
4086}
4087
4088CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregorae185302010-09-16 13:54:00 +00004089 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004090 return clang_getNullCursor();
4091
4092 if (index >= clang_getNumOverloadedDecls(cursor))
4093 return clang_getNullCursor();
4094
Ted Kremenek91554282010-11-16 08:15:36 +00004095 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004096 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4097 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremenek91554282010-11-16 08:15:36 +00004098 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004099
4100 if (OverloadedTemplateStorage *S
4101 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremenek91554282010-11-16 08:15:36 +00004102 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004103
4104 Decl *D = Storage.get<Decl*>();
4105 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4106 // FIXME: This is, unfortunately, linear time.
4107 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4108 std::advance(Pos, index);
Ted Kremenek91554282010-11-16 08:15:36 +00004109 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004110 }
4111
4112 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004113 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004114
4115 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004116 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004117
4118 return clang_getNullCursor();
4119}
4120
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00004121void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff76b8f132009-09-23 17:52:52 +00004122 const char **startBuf,
4123 const char **endBuf,
4124 unsigned *startLine,
4125 unsigned *startColumn,
4126 unsigned *endLine,
Daniel Dunbar079203f2009-12-01 03:14:51 +00004127 unsigned *endColumn) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00004128 assert(getCursorDecl(C) && "CXCursor has null decl");
4129 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff76b8f132009-09-23 17:52:52 +00004130 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4131 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004132
Steve Naroff76b8f132009-09-23 17:52:52 +00004133 SourceManager &SM = FD->getASTContext().getSourceManager();
4134 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4135 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4136 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4137 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4138 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4139 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4140}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004141
Douglas Gregor1e21cc72010-02-18 23:07:20 +00004142void clang_enableStackTraces(void) {
4143 llvm::sys::PrintStackTraceOnErrorSignal();
4144}
4145
Daniel Dunbar23420652010-11-04 01:26:29 +00004146void clang_executeOnThread(void (*fn)(void*), void *user_data,
4147 unsigned stack_size) {
4148 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4149}
4150
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004151} // end: extern "C"
Steve Naroff76b8f132009-09-23 17:52:52 +00004152
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004153//===----------------------------------------------------------------------===//
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004154// Token-based Operations.
4155//===----------------------------------------------------------------------===//
4156
4157/* CXToken layout:
4158 * int_data[0]: a CXTokenKind
4159 * int_data[1]: starting token location
4160 * int_data[2]: token length
4161 * int_data[3]: reserved
Ted Kremenekf441baf2010-02-17 00:41:40 +00004162 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004163 * otherwise unused.
4164 */
4165extern "C" {
4166
4167CXTokenKind clang_getTokenKind(CXToken CXTok) {
4168 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4169}
4170
4171CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4172 switch (clang_getTokenKind(CXTok)) {
4173 case CXToken_Identifier:
4174 case CXToken_Keyword:
4175 // We know we have an IdentifierInfo*, so use that.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004176 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4177 ->getNameStart());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004178
4179 case CXToken_Literal: {
4180 // We have stashed the starting pointer in the ptr_data field. Use it.
4181 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004182 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004183 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004184
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004185 case CXToken_Punctuation:
4186 case CXToken_Comment:
4187 break;
4188 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004189
4190 // We have to find the starting buffer pointer the hard way, by
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004191 // deconstructing the source location.
Ted Kremenek91554282010-11-16 08:15:36 +00004192 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004193 if (!CXXUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004194 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00004195
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004196 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4197 std::pair<FileID, unsigned> LocInfo
4198 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregore0fbb832010-03-16 00:06:06 +00004199 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004200 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004201 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4202 if (Invalid)
Douglas Gregor802b7762010-03-15 22:54:52 +00004203 return createCXString("");
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004204
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004205 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004206}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004207
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004208CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004209 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004210 if (!CXXUnit)
4211 return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004212
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004213 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4214 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4215}
4216
4217CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004218 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4f9c3762010-01-28 00:27:43 +00004219 if (!CXXUnit)
4220 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004221
4222 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004223 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4224}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004225
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004226void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4227 CXToken **Tokens, unsigned *NumTokens) {
4228 if (Tokens)
4229 *Tokens = 0;
4230 if (NumTokens)
4231 *NumTokens = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004232
Ted Kremenek91554282010-11-16 08:15:36 +00004233 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004234 if (!CXXUnit || !Tokens || !NumTokens)
4235 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004236
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004237 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4238
Daniel Dunbar80daf532010-02-14 08:31:57 +00004239 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004240 if (R.isInvalid())
4241 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004242
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004243 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4244 std::pair<FileID, unsigned> BeginLocInfo
4245 = SourceMgr.getDecomposedLoc(R.getBegin());
4246 std::pair<FileID, unsigned> EndLocInfo
4247 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004248
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004249 // Cannot tokenize across files.
4250 if (BeginLocInfo.first != EndLocInfo.first)
4251 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004252
4253 // Create a lexer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004254 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004255 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004256 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor554e0b12010-03-16 20:26:15 +00004257 if (Invalid)
4258 return;
Douglas Gregor802b7762010-03-15 22:54:52 +00004259
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004260 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4261 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004262 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004263 Lex.SetCommentRetentionState(true);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004264
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004265 // Lex tokens until we hit the end of the range.
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004266 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004267 llvm::SmallVector<CXToken, 32> CXTokens;
4268 Token Tok;
David Chisnall1822d1f2010-10-13 21:44:48 +00004269 bool previousWasAt = false;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004270 do {
4271 // Lex the next token
4272 Lex.LexFromRawLexer(Tok);
4273 if (Tok.is(tok::eof))
4274 break;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004275
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004276 // Initialize the CXToken.
4277 CXToken CXTok;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004278
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004279 // - Common fields
4280 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4281 CXTok.int_data[2] = Tok.getLength();
4282 CXTok.int_data[3] = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004283
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004284 // - Kind-specific fields
4285 if (Tok.isLiteral()) {
4286 CXTok.int_data[0] = CXToken_Literal;
4287 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004288 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregor802b7762010-03-15 22:54:52 +00004289 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004290 IdentifierInfo *II
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004291 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004292
David Chisnall1822d1f2010-10-13 21:44:48 +00004293 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004294 CXTok.int_data[0] = CXToken_Keyword;
4295 }
4296 else {
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004297 CXTok.int_data[0] = Tok.is(tok::identifier)
4298 ? CXToken_Identifier
4299 : CXToken_Keyword;
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004300 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004301 CXTok.ptr_data = II;
4302 } else if (Tok.is(tok::comment)) {
4303 CXTok.int_data[0] = CXToken_Comment;
4304 CXTok.ptr_data = 0;
4305 } else {
4306 CXTok.int_data[0] = CXToken_Punctuation;
4307 CXTok.ptr_data = 0;
4308 }
4309 CXTokens.push_back(CXTok);
David Chisnall1822d1f2010-10-13 21:44:48 +00004310 previousWasAt = Tok.is(tok::at);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004311 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004312
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004313 if (CXTokens.empty())
4314 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004315
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004316 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4317 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4318 *NumTokens = CXTokens.size();
4319}
Douglas Gregor61656112010-01-26 18:31:56 +00004320
Ted Kremenek63ac5992010-05-05 00:55:15 +00004321void clang_disposeTokens(CXTranslationUnit TU,
4322 CXToken *Tokens, unsigned NumTokens) {
4323 free(Tokens);
4324}
4325
4326} // end: extern "C"
4327
4328//===----------------------------------------------------------------------===//
4329// Token annotation APIs.
4330//===----------------------------------------------------------------------===//
4331
Douglas Gregor61656112010-01-26 18:31:56 +00004332typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenek680fe512010-05-05 00:55:23 +00004333static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4334 CXCursor parent,
4335 CXClientData client_data);
Ted Kremenek63ac5992010-05-05 00:55:15 +00004336namespace {
4337class AnnotateTokensWorker {
4338 AnnotateTokensData &Annotated;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004339 CXToken *Tokens;
4340 CXCursor *Cursors;
4341 unsigned NumTokens;
Ted Kremenek680fe512010-05-05 00:55:23 +00004342 unsigned TokIdx;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004343 unsigned PreprocessingTokIdx;
Ted Kremenek680fe512010-05-05 00:55:23 +00004344 CursorVisitor AnnotateVis;
4345 SourceManager &SrcMgr;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004346 bool HasContextSensitiveKeywords;
4347
Ted Kremenek680fe512010-05-05 00:55:23 +00004348 bool MoreTokens() const { return TokIdx < NumTokens; }
4349 unsigned NextToken() const { return TokIdx; }
4350 void AdvanceToken() { ++TokIdx; }
4351 SourceLocation GetTokenLoc(unsigned tokI) {
4352 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4353 }
4354
Ted Kremenek63ac5992010-05-05 00:55:15 +00004355public:
Ted Kremenek458c2f12010-05-05 00:55:17 +00004356 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenek680fe512010-05-05 00:55:23 +00004357 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremenek91554282010-11-16 08:15:36 +00004358 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek458c2f12010-05-05 00:55:17 +00004359 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004360 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremenek91554282010-11-16 08:15:36 +00004361 AnnotateVis(tu,
4362 AnnotateTokensVisitor, this,
Douglas Gregorc2b97992011-03-16 23:23:30 +00004363 Decl::MaxPCHLevel, true, RegionOfInterest),
Douglas Gregorf2f08062011-03-08 17:10:18 +00004364 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4365 HasContextSensitiveKeywords(false) { }
Ted Kremenek458c2f12010-05-05 00:55:17 +00004366
Ted Kremenek680fe512010-05-05 00:55:23 +00004367 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004368 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenek680fe512010-05-05 00:55:23 +00004369 void AnnotateTokens(CXCursor parent);
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004370 void AnnotateTokens() {
Ted Kremenek91554282010-11-16 08:15:36 +00004371 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004372 }
Douglas Gregorf2f08062011-03-08 17:10:18 +00004373
4374 /// \brief Determine whether the annotator saw any cursors that have
4375 /// context-sensitive keywords.
4376 bool hasContextSensitiveKeywords() const {
4377 return HasContextSensitiveKeywords;
4378 }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004379};
4380}
Douglas Gregor61656112010-01-26 18:31:56 +00004381
Ted Kremenek680fe512010-05-05 00:55:23 +00004382void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4383 // Walk the AST within the region of interest, annotating tokens
4384 // along the way.
4385 VisitChildren(parent);
Ted Kremenek458c2f12010-05-05 00:55:17 +00004386
Ted Kremenek680fe512010-05-05 00:55:23 +00004387 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4388 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004389 if (Pos != Annotated.end() &&
4390 (clang_isInvalid(Cursors[I].kind) ||
4391 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenek680fe512010-05-05 00:55:23 +00004392 Cursors[I] = Pos->second;
4393 }
4394
4395 // Finish up annotating any tokens left.
4396 if (!MoreTokens())
4397 return;
4398
4399 const CXCursor &C = clang_getNullCursor();
4400 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4401 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4402 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004403 }
4404}
4405
Ted Kremenek63ac5992010-05-05 00:55:15 +00004406enum CXChildVisitResult
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004407AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004408 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004409 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004410 if (cursorRange.isInvalid())
4411 return CXChildVisit_Recurse;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004412
4413 if (!HasContextSensitiveKeywords) {
4414 // Objective-C properties can have context-sensitive keywords.
4415 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4416 if (ObjCPropertyDecl *Property
4417 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4418 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4419 }
4420 // Objective-C methods can have context-sensitive keywords.
4421 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4422 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4423 if (ObjCMethodDecl *Method
4424 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4425 if (Method->getObjCDeclQualifier())
4426 HasContextSensitiveKeywords = true;
4427 else {
4428 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4429 PEnd = Method->param_end();
4430 P != PEnd; ++P) {
4431 if ((*P)->getObjCDeclQualifier()) {
4432 HasContextSensitiveKeywords = true;
4433 break;
4434 }
4435 }
4436 }
4437 }
4438 }
4439 // C++ methods can have context-sensitive keywords.
4440 else if (cursor.kind == CXCursor_CXXMethod) {
4441 if (CXXMethodDecl *Method
4442 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4443 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4444 HasContextSensitiveKeywords = true;
4445 }
4446 }
4447 // C++ classes can have context-sensitive keywords.
4448 else if (cursor.kind == CXCursor_StructDecl ||
4449 cursor.kind == CXCursor_ClassDecl ||
4450 cursor.kind == CXCursor_ClassTemplate ||
4451 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4452 if (Decl *D = getCursorDecl(cursor))
4453 if (D->hasAttr<FinalAttr>())
4454 HasContextSensitiveKeywords = true;
4455 }
4456 }
4457
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004458 if (clang_isPreprocessing(cursor.kind)) {
4459 // For macro instantiations, just note where the beginning of the macro
4460 // instantiation occurs.
4461 if (cursor.kind == CXCursor_MacroInstantiation) {
4462 Annotated[Loc.int_data] = cursor;
4463 return CXChildVisit_Recurse;
4464 }
4465
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004466 // Items in the preprocessing record are kept separate from items in
4467 // declarations, so we keep a separate token index.
4468 unsigned SavedTokIdx = TokIdx;
4469 TokIdx = PreprocessingTokIdx;
4470
4471 // Skip tokens up until we catch up to the beginning of the preprocessing
4472 // entry.
4473 while (MoreTokens()) {
4474 const unsigned I = NextToken();
4475 SourceLocation TokLoc = GetTokenLoc(I);
4476 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4477 case RangeBefore:
4478 AdvanceToken();
4479 continue;
4480 case RangeAfter:
4481 case RangeOverlap:
4482 break;
4483 }
4484 break;
4485 }
4486
4487 // Look at all of the tokens within this range.
4488 while (MoreTokens()) {
4489 const unsigned I = NextToken();
4490 SourceLocation TokLoc = GetTokenLoc(I);
4491 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4492 case RangeBefore:
4493 assert(0 && "Infeasible");
4494 case RangeAfter:
4495 break;
4496 case RangeOverlap:
4497 Cursors[I] = cursor;
4498 AdvanceToken();
4499 continue;
4500 }
4501 break;
4502 }
4503
4504 // Save the preprocessing token index; restore the non-preprocessing
4505 // token index.
4506 PreprocessingTokIdx = TokIdx;
4507 TokIdx = SavedTokIdx;
Douglas Gregor61656112010-01-26 18:31:56 +00004508 return CXChildVisit_Recurse;
4509 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004510
Ted Kremenek680fe512010-05-05 00:55:23 +00004511 if (cursorRange.isInvalid())
4512 return CXChildVisit_Continue;
Ted Kremenek5d616142010-05-12 05:29:33 +00004513
Ted Kremenek680fe512010-05-05 00:55:23 +00004514 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4515
Ted Kremenek5d616142010-05-12 05:29:33 +00004516 // Adjust the annotated range based specific declarations.
4517 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4518 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek49be9e02010-05-18 21:09:07 +00004519 Decl *D = cxcursor::getCursorDecl(cursor);
4520 // Don't visit synthesized ObjC methods, since they have no syntatic
4521 // representation in the source.
4522 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4523 if (MD->isSynthesized())
4524 return CXChildVisit_Continue;
4525 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004526
4527 SourceLocation StartLoc;
Ted Kremenek49be9e02010-05-18 21:09:07 +00004528 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004529 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4530 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4531 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4532 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4533 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremenek5d616142010-05-12 05:29:33 +00004534 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004535
4536 if (StartLoc.isValid() && L.isValid() &&
4537 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4538 cursorRange.setBegin(StartLoc);
Ted Kremenek5d616142010-05-12 05:29:33 +00004539 }
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004540
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004541 // If the location of the cursor occurs within a macro instantiation, record
4542 // the spelling location of the cursor in our annotation map. We can then
4543 // paper over the token labelings during a post-processing step to try and
4544 // get cursor mappings for tokens that are the *arguments* of a macro
4545 // instantiation.
4546 if (L.isMacroID()) {
4547 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4548 // Only invalidate the old annotation if it isn't part of a preprocessing
4549 // directive. Here we assume that the default construction of CXCursor
4550 // results in CXCursor.kind being an initialized value (i.e., 0). If
4551 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004552
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004553 CXCursor &oldC = Annotated[rawEncoding];
4554 if (!clang_isPreprocessing(oldC.kind))
4555 oldC = cursor;
4556 }
4557
Ted Kremenek680fe512010-05-05 00:55:23 +00004558 const enum CXCursorKind K = clang_getCursorKind(parent);
4559 const CXCursor updateC =
Ted Kremenek65b2cc02010-08-25 22:16:02 +00004560 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4561 ? clang_getNullCursor() : parent;
Ted Kremenek680fe512010-05-05 00:55:23 +00004562
4563 while (MoreTokens()) {
4564 const unsigned I = NextToken();
4565 SourceLocation TokLoc = GetTokenLoc(I);
4566 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4567 case RangeBefore:
4568 Cursors[I] = updateC;
4569 AdvanceToken();
4570 continue;
4571 case RangeAfter:
Ted Kremenek680fe512010-05-05 00:55:23 +00004572 case RangeOverlap:
4573 break;
4574 }
4575 break;
4576 }
4577
4578 // Visit children to get their cursor information.
4579 const unsigned BeforeChildren = NextToken();
4580 VisitChildren(cursor);
4581 const unsigned AfterChildren = NextToken();
4582
4583 // Adjust 'Last' to the last token within the extent of the cursor.
4584 while (MoreTokens()) {
4585 const unsigned I = NextToken();
4586 SourceLocation TokLoc = GetTokenLoc(I);
4587 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4588 case RangeBefore:
4589 assert(0 && "Infeasible");
4590 case RangeAfter:
4591 break;
4592 case RangeOverlap:
4593 Cursors[I] = updateC;
4594 AdvanceToken();
4595 continue;
4596 }
4597 break;
4598 }
4599 const unsigned Last = NextToken();
Ted Kremenek63ac5992010-05-05 00:55:15 +00004600
Ted Kremenek680fe512010-05-05 00:55:23 +00004601 // Scan the tokens that are at the beginning of the cursor, but are not
4602 // capture by the child cursors.
4603
4604 // For AST elements within macros, rely on a post-annotate pass to
4605 // to correctly annotate the tokens with cursors. Otherwise we can
4606 // get confusing results of having tokens that map to cursors that really
4607 // are expanded by an instantiation.
4608 if (L.isMacroID())
4609 cursor = clang_getNullCursor();
4610
4611 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4612 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4613 break;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004614
Ted Kremenek680fe512010-05-05 00:55:23 +00004615 Cursors[I] = cursor;
4616 }
4617 // Scan the tokens that are at the end of the cursor, but are not captured
4618 // but the child cursors.
4619 for (unsigned I = AfterChildren; I != Last; ++I)
4620 Cursors[I] = cursor;
4621
4622 TokIdx = Last;
4623 return CXChildVisit_Continue;
Douglas Gregor61656112010-01-26 18:31:56 +00004624}
4625
Ted Kremenek63ac5992010-05-05 00:55:15 +00004626static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4627 CXCursor parent,
4628 CXClientData client_data) {
4629 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4630}
4631
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004632namespace {
4633 struct clang_annotateTokens_Data {
4634 CXTranslationUnit TU;
4635 ASTUnit *CXXUnit;
4636 CXToken *Tokens;
4637 unsigned NumTokens;
4638 CXCursor *Cursors;
4639 };
4640}
4641
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004642// This gets run a separate thread to avoid stack blowout.
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004643static void clang_annotateTokensImpl(void *UserData) {
4644 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
4645 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
4646 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
4647 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
4648 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4649
4650 // Determine the region of interest, which contains all of the tokens.
4651 SourceRange RegionOfInterest;
4652 RegionOfInterest.setBegin(
4653 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
4654 RegionOfInterest.setEnd(
4655 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
4656 Tokens[NumTokens-1])));
4657
4658 // A mapping from the source locations found when re-lexing or traversing the
4659 // region of interest to the corresponding cursors.
4660 AnnotateTokensData Annotated;
4661
4662 // Relex the tokens within the source range to look for preprocessing
4663 // directives.
4664 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4665 std::pair<FileID, unsigned> BeginLocInfo
4666 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4667 std::pair<FileID, unsigned> EndLocInfo
4668 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
4669
4670 llvm::StringRef Buffer;
4671 bool Invalid = false;
4672 if (BeginLocInfo.first == EndLocInfo.first &&
4673 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4674 !Invalid) {
4675 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4676 CXXUnit->getASTContext().getLangOptions(),
4677 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
4678 Buffer.end());
4679 Lex.SetCommentRetentionState(true);
4680
4681 // Lex tokens in raw mode until we hit the end of the range, to avoid
4682 // entering #includes or expanding macros.
4683 while (true) {
4684 Token Tok;
4685 Lex.LexFromRawLexer(Tok);
4686
4687 reprocess:
4688 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4689 // We have found a preprocessing directive. Gobble it up so that we
4690 // don't see it while preprocessing these tokens later, but keep track
4691 // of all of the token locations inside this preprocessing directive so
4692 // that we can annotate them appropriately.
4693 //
4694 // FIXME: Some simple tests here could identify macro definitions and
4695 // #undefs, to provide specific cursor kinds for those.
4696 llvm::SmallVector<SourceLocation, 32> Locations;
4697 do {
4698 Locations.push_back(Tok.getLocation());
4699 Lex.LexFromRawLexer(Tok);
4700 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
4701
4702 using namespace cxcursor;
4703 CXCursor Cursor
4704 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4705 Locations.back()),
4706 TU);
4707 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4708 Annotated[Locations[I].getRawEncoding()] = Cursor;
4709 }
4710
4711 if (Tok.isAtStartOfLine())
4712 goto reprocess;
4713
4714 continue;
4715 }
4716
4717 if (Tok.is(tok::eof))
4718 break;
4719 }
4720 }
4721
4722 // Annotate all of the source locations in the region of interest that map to
4723 // a specific cursor.
4724 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
4725 TU, RegionOfInterest);
4726
4727 // FIXME: We use a ridiculous stack size here because the data-recursion
4728 // algorithm uses a large stack frame than the non-data recursive version,
4729 // and AnnotationTokensWorker currently transforms the data-recursion
4730 // algorithm back into a traditional recursion by explicitly calling
4731 // VisitChildren(). We will need to remove this explicit recursive call.
4732 W.AnnotateTokens();
4733
4734 // If we ran into any entities that involve context-sensitive keywords,
4735 // take another pass through the tokens to mark them as such.
4736 if (W.hasContextSensitiveKeywords()) {
4737 for (unsigned I = 0; I != NumTokens; ++I) {
4738 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4739 continue;
4740
4741 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4742 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4743 if (ObjCPropertyDecl *Property
4744 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4745 if (Property->getPropertyAttributesAsWritten() != 0 &&
4746 llvm::StringSwitch<bool>(II->getName())
4747 .Case("readonly", true)
4748 .Case("assign", true)
4749 .Case("readwrite", true)
4750 .Case("retain", true)
4751 .Case("copy", true)
4752 .Case("nonatomic", true)
4753 .Case("atomic", true)
4754 .Case("getter", true)
4755 .Case("setter", true)
4756 .Default(false))
4757 Tokens[I].int_data[0] = CXToken_Keyword;
4758 }
4759 continue;
4760 }
4761
4762 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4763 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4764 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4765 if (llvm::StringSwitch<bool>(II->getName())
4766 .Case("in", true)
4767 .Case("out", true)
4768 .Case("inout", true)
4769 .Case("oneway", true)
4770 .Case("bycopy", true)
4771 .Case("byref", true)
4772 .Default(false))
4773 Tokens[I].int_data[0] = CXToken_Keyword;
4774 continue;
4775 }
4776
4777 if (Cursors[I].kind == CXCursor_CXXMethod) {
4778 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4779 if (CXXMethodDecl *Method
4780 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4781 if ((Method->hasAttr<FinalAttr>() ||
4782 Method->hasAttr<OverrideAttr>()) &&
4783 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4784 llvm::StringSwitch<bool>(II->getName())
4785 .Case("final", true)
4786 .Case("override", true)
4787 .Default(false))
4788 Tokens[I].int_data[0] = CXToken_Keyword;
4789 }
4790 continue;
4791 }
4792
4793 if (Cursors[I].kind == CXCursor_ClassDecl ||
4794 Cursors[I].kind == CXCursor_StructDecl ||
4795 Cursors[I].kind == CXCursor_ClassTemplate) {
4796 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4797 if (II->getName() == "final") {
4798 // We have to be careful with 'final', since it could be the name
4799 // of a member class rather than the context-sensitive keyword.
4800 // So, check whether the cursor associated with this
4801 Decl *D = getCursorDecl(Cursors[I]);
4802 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4803 if ((Record->hasAttr<FinalAttr>()) &&
4804 Record->getIdentifier() != II)
4805 Tokens[I].int_data[0] = CXToken_Keyword;
4806 } else if (ClassTemplateDecl *ClassTemplate
4807 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4808 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4809 if ((Record->hasAttr<FinalAttr>()) &&
4810 Record->getIdentifier() != II)
4811 Tokens[I].int_data[0] = CXToken_Keyword;
4812 }
4813 }
4814 continue;
4815 }
4816 }
4817 }
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004818}
4819
Ted Kremenek63ac5992010-05-05 00:55:15 +00004820extern "C" {
4821
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004822void clang_annotateTokens(CXTranslationUnit TU,
4823 CXToken *Tokens, unsigned NumTokens,
4824 CXCursor *Cursors) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004825
4826 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor61656112010-01-26 18:31:56 +00004827 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004828
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004829 // Any token we don't specifically annotate will have a NULL cursor.
4830 CXCursor C = clang_getNullCursor();
4831 for (unsigned I = 0; I != NumTokens; ++I)
4832 Cursors[I] = C;
4833
Ted Kremenek91554282010-11-16 08:15:36 +00004834 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004835 if (!CXXUnit)
Douglas Gregor61656112010-01-26 18:31:56 +00004836 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004837
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004838 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004839
4840 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004841 llvm::CrashRecoveryContext CRC;
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004842 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
Ted Kremenekca817a3c2010-11-14 17:47:35 +00004843 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004844 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4845 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004846}
Ted Kremenek21c7e6e2011-03-18 22:51:30 +00004847
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004848} // end: extern "C"
4849
4850//===----------------------------------------------------------------------===//
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004851// Operations for querying linkage of a cursor.
4852//===----------------------------------------------------------------------===//
4853
4854extern "C" {
4855CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor5272e802010-03-19 05:22:59 +00004856 if (!clang_isDeclaration(cursor.kind))
4857 return CXLinkage_Invalid;
4858
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004859 Decl *D = cxcursor::getCursorDecl(cursor);
4860 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4861 switch (ND->getLinkage()) {
4862 case NoLinkage: return CXLinkage_NoLinkage;
4863 case InternalLinkage: return CXLinkage_Internal;
4864 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4865 case ExternalLinkage: return CXLinkage_External;
4866 };
4867
4868 return CXLinkage_Invalid;
4869}
4870} // end: extern "C"
4871
4872//===----------------------------------------------------------------------===//
Ted Kremenek4ed29252010-04-12 21:22:16 +00004873// Operations for querying language of a cursor.
4874//===----------------------------------------------------------------------===//
4875
4876static CXLanguageKind getDeclLanguage(const Decl *D) {
4877 switch (D->getKind()) {
4878 default:
4879 break;
4880 case Decl::ImplicitParam:
4881 case Decl::ObjCAtDefsField:
4882 case Decl::ObjCCategory:
4883 case Decl::ObjCCategoryImpl:
4884 case Decl::ObjCClass:
4885 case Decl::ObjCCompatibleAlias:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004886 case Decl::ObjCForwardProtocol:
4887 case Decl::ObjCImplementation:
4888 case Decl::ObjCInterface:
4889 case Decl::ObjCIvar:
4890 case Decl::ObjCMethod:
4891 case Decl::ObjCProperty:
4892 case Decl::ObjCPropertyImpl:
4893 case Decl::ObjCProtocol:
4894 return CXLanguage_ObjC;
4895 case Decl::CXXConstructor:
4896 case Decl::CXXConversion:
4897 case Decl::CXXDestructor:
4898 case Decl::CXXMethod:
4899 case Decl::CXXRecord:
4900 case Decl::ClassTemplate:
4901 case Decl::ClassTemplatePartialSpecialization:
4902 case Decl::ClassTemplateSpecialization:
4903 case Decl::Friend:
4904 case Decl::FriendTemplate:
4905 case Decl::FunctionTemplate:
4906 case Decl::LinkageSpec:
4907 case Decl::Namespace:
4908 case Decl::NamespaceAlias:
4909 case Decl::NonTypeTemplateParm:
4910 case Decl::StaticAssert:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004911 case Decl::TemplateTemplateParm:
4912 case Decl::TemplateTypeParm:
4913 case Decl::UnresolvedUsingTypename:
4914 case Decl::UnresolvedUsingValue:
4915 case Decl::Using:
4916 case Decl::UsingDirective:
4917 case Decl::UsingShadow:
4918 return CXLanguage_CPlusPlus;
4919 }
4920
4921 return CXLanguage_C;
4922}
4923
4924extern "C" {
Douglas Gregorf757a122010-08-23 23:00:57 +00004925
4926enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4927 if (clang_isDeclaration(cursor.kind))
4928 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004929 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Douglas Gregorf757a122010-08-23 23:00:57 +00004930 return CXAvailability_Available;
4931
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004932 switch (D->getAvailability()) {
4933 case AR_Available:
4934 case AR_NotYetIntroduced:
4935 return CXAvailability_Available;
4936
4937 case AR_Deprecated:
Douglas Gregorf757a122010-08-23 23:00:57 +00004938 return CXAvailability_Deprecated;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004939
4940 case AR_Unavailable:
4941 return CXAvailability_NotAvailable;
4942 }
Douglas Gregorf757a122010-08-23 23:00:57 +00004943 }
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00004944
Douglas Gregorf757a122010-08-23 23:00:57 +00004945 return CXAvailability_Available;
4946}
4947
Ted Kremenek4ed29252010-04-12 21:22:16 +00004948CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4949 if (clang_isDeclaration(cursor.kind))
4950 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4951
4952 return CXLanguage_Invalid;
4953}
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004954
4955 /// \brief If the given cursor is the "templated" declaration
4956 /// descibing a class or function template, return the class or
4957 /// function template.
4958static Decl *maybeGetTemplateCursor(Decl *D) {
4959 if (!D)
4960 return 0;
4961
4962 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4963 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4964 return FunTmpl;
4965
4966 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4967 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4968 return ClassTmpl;
4969
4970 return D;
4971}
4972
Douglas Gregor0576ce72010-09-22 21:22:29 +00004973CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4974 if (clang_isDeclaration(cursor.kind)) {
4975 if (Decl *D = getCursorDecl(cursor)) {
4976 DeclContext *DC = D->getDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004977 if (!DC)
4978 return clang_getNullCursor();
4979
4980 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4981 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004982 }
4983 }
4984
4985 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4986 if (Decl *D = getCursorDecl(cursor))
Ted Kremenek91554282010-11-16 08:15:36 +00004987 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004988 }
4989
4990 return clang_getNullCursor();
4991}
4992
4993CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4994 if (clang_isDeclaration(cursor.kind)) {
4995 if (Decl *D = getCursorDecl(cursor)) {
4996 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004997 if (!DC)
4998 return clang_getNullCursor();
4999
5000 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5001 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00005002 }
5003 }
5004
5005 // FIXME: Note that we can't easily compute the lexical context of a
5006 // statement or expression, so we return nothing.
5007 return clang_getNullCursor();
5008}
5009
Douglas Gregor99a26af2010-10-01 20:25:15 +00005010static void CollectOverriddenMethods(DeclContext *Ctx,
5011 ObjCMethodDecl *Method,
5012 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
5013 if (!Ctx)
5014 return;
5015
5016 // If we have a class or category implementation, jump straight to the
5017 // interface.
5018 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
5019 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
5020
5021 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
5022 if (!Container)
5023 return;
5024
5025 // Check whether we have a matching method at this level.
5026 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
5027 Method->isInstanceMethod()))
5028 if (Method != Overridden) {
5029 // We found an override at this level; there is no need to look
5030 // into other protocols or categories.
5031 Methods.push_back(Overridden);
5032 return;
5033 }
5034
5035 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
5036 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
5037 PEnd = Protocol->protocol_end();
5038 P != PEnd; ++P)
5039 CollectOverriddenMethods(*P, Method, Methods);
5040 }
5041
5042 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
5043 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
5044 PEnd = Category->protocol_end();
5045 P != PEnd; ++P)
5046 CollectOverriddenMethods(*P, Method, Methods);
5047 }
5048
5049 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
5050 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
5051 PEnd = Interface->protocol_end();
5052 P != PEnd; ++P)
5053 CollectOverriddenMethods(*P, Method, Methods);
5054
5055 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
5056 Category; Category = Category->getNextClassCategory())
5057 CollectOverriddenMethods(Category, Method, Methods);
5058
5059 // We only look into the superclass if we haven't found anything yet.
5060 if (Methods.empty())
5061 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
5062 return CollectOverriddenMethods(Super, Method, Methods);
5063 }
5064}
5065
5066void clang_getOverriddenCursors(CXCursor cursor,
5067 CXCursor **overridden,
5068 unsigned *num_overridden) {
5069 if (overridden)
5070 *overridden = 0;
5071 if (num_overridden)
5072 *num_overridden = 0;
5073 if (!overridden || !num_overridden)
5074 return;
5075
5076 if (!clang_isDeclaration(cursor.kind))
5077 return;
5078
5079 Decl *D = getCursorDecl(cursor);
5080 if (!D)
5081 return;
5082
5083 // Handle C++ member functions.
Ted Kremenek91554282010-11-16 08:15:36 +00005084 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005085 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
5086 *num_overridden = CXXMethod->size_overridden_methods();
5087 if (!*num_overridden)
5088 return;
5089
5090 *overridden = new CXCursor [*num_overridden];
5091 unsigned I = 0;
5092 for (CXXMethodDecl::method_iterator
5093 M = CXXMethod->begin_overridden_methods(),
5094 MEnd = CXXMethod->end_overridden_methods();
5095 M != MEnd; (void)++M, ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00005096 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005097 return;
5098 }
5099
5100 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
5101 if (!Method)
5102 return;
5103
5104 // Handle Objective-C methods.
5105 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5106 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5107
5108 if (Methods.empty())
5109 return;
5110
5111 *num_overridden = Methods.size();
5112 *overridden = new CXCursor [Methods.size()];
5113 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00005114 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005115}
5116
5117void clang_disposeOverriddenCursors(CXCursor *overridden) {
5118 delete [] overridden;
5119}
5120
Douglas Gregor796d76a2010-10-20 22:00:55 +00005121CXFile clang_getIncludedFile(CXCursor cursor) {
5122 if (cursor.kind != CXCursor_InclusionDirective)
5123 return 0;
5124
5125 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5126 return (void *)ID->getFile();
5127}
5128
Ted Kremenek4ed29252010-04-12 21:22:16 +00005129} // end: extern "C"
5130
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005131
5132//===----------------------------------------------------------------------===//
5133// C++ AST instrospection.
5134//===----------------------------------------------------------------------===//
5135
5136extern "C" {
5137unsigned clang_CXXMethod_isStatic(CXCursor C) {
5138 if (!clang_isDeclaration(C.kind))
5139 return 0;
Douglas Gregorf11309e2010-08-31 22:12:17 +00005140
5141 CXXMethodDecl *Method = 0;
5142 Decl *D = cxcursor::getCursorDecl(C);
5143 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5144 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5145 else
5146 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5147 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek0ed75492010-05-17 20:12:45 +00005148}
Ted Kremeneka10f1282010-05-18 22:32:15 +00005149
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005150} // end: extern "C"
5151
Ted Kremenek4ed29252010-04-12 21:22:16 +00005152//===----------------------------------------------------------------------===//
Ted Kremeneka5940822010-08-26 01:42:22 +00005153// Attribute introspection.
5154//===----------------------------------------------------------------------===//
5155
5156extern "C" {
5157CXType clang_getIBOutletCollectionType(CXCursor C) {
5158 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremenek91554282010-11-16 08:15:36 +00005159 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005160
5161 IBOutletCollectionAttr *A =
5162 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5163
Douglas Gregorc81a7a22011-03-06 18:55:32 +00005164 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005165}
5166} // end: extern "C"
5167
5168//===----------------------------------------------------------------------===//
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005169// Misc. utility functions.
5170//===----------------------------------------------------------------------===//
Ted Kremenekf441baf2010-02-17 00:41:40 +00005171
Daniel Dunbar087c3a32010-11-05 17:21:46 +00005172/// Default to using an 8 MB stack size on "safety" threads.
5173static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005174
5175namespace clang {
5176
5177bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenekca817a3c2010-11-14 17:47:35 +00005178 void (*Fn)(void*), void *UserData,
5179 unsigned Size) {
5180 if (!Size)
5181 Size = GetSafetyThreadStackSize();
5182 if (Size)
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005183 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5184 return CRC.RunSafely(Fn, UserData);
5185}
5186
5187unsigned GetSafetyThreadStackSize() {
5188 return SafetyStackThreadSize;
5189}
5190
5191void SetSafetyThreadStackSize(unsigned Value) {
5192 SafetyStackThreadSize = Value;
5193}
5194
5195}
5196
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005197extern "C" {
5198
Ted Kremeneka3e65702010-02-12 22:54:40 +00005199CXString clang_getClangVersion() {
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00005200 return createCXString(getClangFullVersion());
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005201}
5202
5203} // end: extern "C"