blob: 16672ca70401f8036d9a7c8478c863d5a2de1dde [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
191 /// \brief When valid, a source range to which the cursor should restrict
192 /// its search.
193 SourceRange RegionOfInterest;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000194
Ted Kremenekd40a4392010-11-02 23:10:24 +0000195 // FIXME: Eventually remove. This part of a hack to support proper
196 // iteration over all Decls contained lexically within an ObjC container.
197 DeclContext::decl_iterator *DI_current;
198 DeclContext::decl_iterator DE_current;
199
Ted Kremeneka4c27ec2010-11-15 23:31:32 +0000200 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
201 llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
202 llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
203
Douglas Gregor71f3d942010-01-20 20:59:29 +0000204 using DeclVisitor<CursorVisitor, bool>::Visit;
Douglas Gregor93f89952010-01-21 16:28:34 +0000205 using TypeLocVisitor<CursorVisitor, bool>::Visit;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000206
207 /// \brief Determine whether this particular source range comes before, comes
208 /// after, or overlaps the region of interest.
Douglas Gregor562c1f92010-01-22 19:49:59 +0000209 ///
Daniel Dunbar02968e52010-02-14 10:02:57 +0000210 /// \param R a half-open source range retrieved from the abstract syntax tree.
Ted Kremenekf441baf2010-02-17 00:41:40 +0000211 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
212
Ted Kremenek12e0f292010-05-13 00:25:00 +0000213 class SetParentRAII {
214 CXCursor &Parent;
215 Decl *&StmtParent;
216 CXCursor OldParent;
217
218 public:
219 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
220 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
221 {
222 Parent = NewParent;
223 if (clang_isDeclaration(Parent.kind))
224 StmtParent = getCursorDecl(Parent);
225 }
226
227 ~SetParentRAII() {
228 Parent = OldParent;
229 if (clang_isDeclaration(Parent.kind))
230 StmtParent = getCursorDecl(Parent);
231 }
232 };
233
Steve Naroff1054e602009-08-31 00:59:03 +0000234public:
Ted Kremenek91554282010-11-16 08:15:36 +0000235 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
236 CXClientData ClientData,
Ted Kremenekf441baf2010-02-17 00:41:40 +0000237 unsigned MaxPCHLevel,
Douglas Gregor562c1f92010-01-22 19:49:59 +0000238 SourceRange RegionOfInterest = SourceRange())
Ted Kremenek91554282010-11-16 08:15:36 +0000239 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
240 Visitor(Visitor), ClientData(ClientData),
Ted Kremenekd40a4392010-11-02 23:10:24 +0000241 MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest),
242 DI_current(0)
Douglas Gregor71f3d942010-01-20 20:59:29 +0000243 {
244 Parent.kind = CXCursor_NoDeclFound;
245 Parent.data[0] = 0;
246 Parent.data[1] = 0;
247 Parent.data[2] = 0;
Douglas Gregord1824312010-01-21 17:29:07 +0000248 StmtParent = 0;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000249 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000250
Ted Kremeneka4c27ec2010-11-15 23:31:32 +0000251 ~CursorVisitor() {
252 // Free the pre-allocated worklists for data-recursion.
253 for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
254 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
255 delete *I;
256 }
257 }
258
Ted Kremenek91554282010-11-16 08:15:36 +0000259 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
260 CXTranslationUnit getTU() const { return TU; }
Ted Kremenekc7a5bae2010-11-11 08:05:23 +0000261
Douglas Gregor562c1f92010-01-22 19:49:59 +0000262 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000263
264 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
265 getPreprocessedEntities();
266
Douglas Gregor71f3d942010-01-20 20:59:29 +0000267 bool VisitChildren(CXCursor Parent);
Ted Kremenekf441baf2010-02-17 00:41:40 +0000268
Douglas Gregor93f89952010-01-21 16:28:34 +0000269 // Declaration visitors
Ted Kremenek6ab9aa022010-02-18 05:46:33 +0000270 bool VisitAttributes(Decl *D);
Ted Kremenek33b9a422010-04-11 21:47:37 +0000271 bool VisitBlockDecl(BlockDecl *B);
Ted Kremenekae9e2212010-08-27 21:34:58 +0000272 bool VisitCXXRecordDecl(CXXRecordDecl *D);
Ted Kremenekd40a4392010-11-02 23:10:24 +0000273 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
Douglas Gregor71f3d942010-01-20 20:59:29 +0000274 bool VisitDeclContext(DeclContext *DC);
Ted Kremenek7dff4162010-02-18 18:47:08 +0000275 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
276 bool VisitTypedefDecl(TypedefDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000277 bool VisitTagDecl(TagDecl *D);
Douglas Gregor9dc243c2010-09-01 17:32:36 +0000278 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
Douglas Gregorf96abb22010-08-31 19:31:58 +0000279 bool VisitClassTemplatePartialSpecializationDecl(
280 ClassTemplatePartialSpecializationDecl *D);
Douglas Gregor713602b2010-08-31 17:01:39 +0000281 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000282 bool VisitEnumConstantDecl(EnumConstantDecl *D);
283 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
284 bool VisitFunctionDecl(FunctionDecl *ND);
285 bool VisitFieldDecl(FieldDecl *D);
Ted Kremenek7dff4162010-02-18 18:47:08 +0000286 bool VisitVarDecl(VarDecl *);
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000287 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Douglas Gregor713602b2010-08-31 17:01:39 +0000288 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
Douglas Gregor1fbaeb12010-08-31 19:02:00 +0000289 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000290 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000291 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
292 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
293 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
294 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
Ted Kremenek49be9e02010-05-18 21:09:07 +0000295 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
Ted Kremeneke2110252010-02-18 22:36:18 +0000296 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
297 bool VisitObjCImplDecl(ObjCImplDecl *D);
298 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
299 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
Ted Kremeneke2110252010-02-18 22:36:18 +0000300 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
301 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
302 bool VisitObjCClassDecl(ObjCClassDecl *D);
Douglas Gregorb1b71e52010-11-17 01:03:52 +0000303 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
Ted Kremenekb80cba52010-05-07 01:04:29 +0000304 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
Ted Kremenekbd67fb22010-05-06 23:38:21 +0000305 bool VisitNamespaceDecl(NamespaceDecl *D);
Douglas Gregora89314e2010-08-31 23:48:11 +0000306 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Douglas Gregor01a430132010-09-01 03:07:18 +0000307 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
Douglas Gregora9aa29c2010-09-01 19:52:22 +0000308 bool VisitUsingDecl(UsingDecl *D);
309 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
310 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
Douglas Gregor01a430132010-09-01 03:07:18 +0000311
Douglas Gregor12bca222010-08-31 14:41:23 +0000312 // Name visitor
313 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
Douglas Gregor3335f482010-09-02 17:35:32 +0000314 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
Douglas Gregora9d87bc2011-02-25 00:36:19 +0000315 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
Douglas Gregor12bca222010-08-31 14:41:23 +0000316
Douglas Gregor713602b2010-08-31 17:01:39 +0000317 // Template visitors
318 bool VisitTemplateParameters(const TemplateParameterList *Params);
Douglas Gregora23e8f72010-08-31 20:37:03 +0000319 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
Douglas Gregor713602b2010-08-31 17:01:39 +0000320 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
321
Douglas Gregor93f89952010-01-21 16:28:34 +0000322 // Type visitors
Douglas Gregor12bca222010-08-31 14:41:23 +0000323 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000324 bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
Douglas Gregor93f89952010-01-21 16:28:34 +0000325 bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000326 bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
327 bool VisitTagTypeLoc(TagTypeLoc TL);
Douglas Gregor713602b2010-08-31 17:01:39 +0000328 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000329 bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
John McCall8b07ec22010-05-15 11:32:37 +0000330 bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000331 bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
Abramo Bagnara924a8f32010-12-10 16:29:40 +0000332 bool VisitParenTypeLoc(ParenTypeLoc TL);
Douglas Gregord1824312010-01-21 17:29:07 +0000333 bool VisitPointerTypeLoc(PointerTypeLoc TL);
334 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
335 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
336 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
337 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
Douglas Gregor12bca222010-08-31 14:41:23 +0000338 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
Douglas Gregord1824312010-01-21 17:29:07 +0000339 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
Douglas Gregor713602b2010-08-31 17:01:39 +0000340 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
Douglas Gregor6479fc42010-01-21 20:48:56 +0000341 // FIXME: Implement visitors here when the unimplemented TypeLocs get
342 // implemented
343 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
Douglas Gregord2fa7662010-12-20 02:24:11 +0000344 bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
Douglas Gregor6479fc42010-01-21 20:48:56 +0000345 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
Douglas Gregor3d0da5f2011-03-01 01:34:45 +0000346 bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
Douglas Gregora7a795b2011-03-01 20:11:18 +0000347 bool VisitDependentTemplateSpecializationTypeLoc(
348 DependentTemplateSpecializationTypeLoc TL);
Douglas Gregor844cb502011-03-01 18:12:44 +0000349 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
Douglas Gregor3d0da5f2011-03-01 01:34:45 +0000350
Ted Kremenek92209a42010-11-11 08:05:18 +0000351 // Data-recursive visitor functions.
352 bool IsInRegionOfInterest(CXCursor C);
353 bool RunVisitorWorkList(VisitorWorkList &WL);
354 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
Ted Kremenek5d304a32010-11-18 00:42:18 +0000355 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
Steve Naroff1054e602009-08-31 00:59:03 +0000356};
Ted Kremenekf441baf2010-02-17 00:41:40 +0000357
Ted Kremenek0ec2cca2010-01-05 19:32:54 +0000358} // end anonymous namespace
Benjamin Kramer61f5d0c2009-10-18 16:11:04 +0000359
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000360static SourceRange getRawCursorExtent(CXCursor C);
Douglas Gregor29ee4222010-11-17 17:14:07 +0000361static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
362
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000363
Douglas Gregor562c1f92010-01-22 19:49:59 +0000364RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
Ted Kremenek91554282010-11-16 08:15:36 +0000365 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
Douglas Gregor562c1f92010-01-22 19:49:59 +0000366}
367
Douglas Gregor71f3d942010-01-20 20:59:29 +0000368/// \brief Visit the given cursor and, if requested by the visitor,
369/// its children.
370///
Douglas Gregor562c1f92010-01-22 19:49:59 +0000371/// \param Cursor the cursor to visit.
372///
373/// \param CheckRegionOfInterest if true, then the caller already checked that
374/// this cursor is within the region of interest.
375///
Douglas Gregor71f3d942010-01-20 20:59:29 +0000376/// \returns true if the visitation should be aborted, false if it
377/// should continue.
Douglas Gregor562c1f92010-01-22 19:49:59 +0000378bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
Douglas Gregor71f3d942010-01-20 20:59:29 +0000379 if (clang_isInvalid(Cursor.kind))
380 return false;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000381
Douglas Gregor71f3d942010-01-20 20:59:29 +0000382 if (clang_isDeclaration(Cursor.kind)) {
383 Decl *D = getCursorDecl(Cursor);
384 assert(D && "Invalid declaration cursor");
385 if (D->getPCHLevel() > MaxPCHLevel)
386 return false;
387
388 if (D->isImplicit())
389 return false;
390 }
391
Douglas Gregor562c1f92010-01-22 19:49:59 +0000392 // If we have a range of interest, and this cursor doesn't intersect with it,
393 // we're done.
394 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
Douglas Gregorcd8bdd02010-07-22 20:22:31 +0000395 SourceRange Range = getRawCursorExtent(Cursor);
Daniel Dunbar2f4ba172010-02-14 08:32:05 +0000396 if (Range.isInvalid() || CompareRegionOfInterest(Range))
Douglas Gregor562c1f92010-01-22 19:49:59 +0000397 return false;
398 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000399
Douglas Gregor71f3d942010-01-20 20:59:29 +0000400 switch (Visitor(Cursor, Parent, ClientData)) {
401 case CXChildVisit_Break:
402 return true;
403
404 case CXChildVisit_Continue:
405 return false;
406
407 case CXChildVisit_Recurse:
408 return VisitChildren(Cursor);
409 }
410
Douglas Gregor33f16852010-01-25 16:45:46 +0000411 return false;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000412}
413
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000414std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
415CursorVisitor::getPreprocessedEntities() {
416 PreprocessingRecord &PPRec
Ted Kremenek91554282010-11-16 08:15:36 +0000417 = *AU->getPreprocessor().getPreprocessingRecord();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000418
419 bool OnlyLocalDecls
Douglas Gregorfd4da712010-12-21 19:07:48 +0000420 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
421
422 if (OnlyLocalDecls && RegionOfInterest.isValid()) {
423 // If we would only look at local declarations but we have a region of
424 // interest, check whether that region of interest is in the main file.
425 // If not, we should traverse all declarations.
426 // FIXME: My kingdom for a proper binary search approach to finding
427 // cursors!
428 std::pair<FileID, unsigned> Location
429 = AU->getSourceManager().getDecomposedInstantiationLoc(
430 RegionOfInterest.getBegin());
431 if (Location.first != AU->getSourceManager().getMainFileID())
432 OnlyLocalDecls = false;
433 }
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000434
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000435 PreprocessingRecord::iterator StartEntity, EndEntity;
436 if (OnlyLocalDecls) {
437 StartEntity = AU->pp_entity_begin();
438 EndEntity = AU->pp_entity_end();
439 } else {
440 StartEntity = PPRec.begin();
441 EndEntity = PPRec.end();
442 }
443
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000444 // There is no region of interest; we have to walk everything.
445 if (RegionOfInterest.isInvalid())
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000446 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000447
448 // Find the file in which the region of interest lands.
Ted Kremenek91554282010-11-16 08:15:36 +0000449 SourceManager &SM = AU->getSourceManager();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000450 std::pair<FileID, unsigned> Begin
451 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
452 std::pair<FileID, unsigned> End
453 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
454
455 // The region of interest spans files; we have to walk everything.
456 if (Begin.first != End.first)
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000457 return std::make_pair(StartEntity, EndEntity);
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000458
459 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
Ted Kremenek91554282010-11-16 08:15:36 +0000460 = AU->getPreprocessedEntitiesByFile();
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000461 if (ByFileMap.empty()) {
462 // Build the mapping from files to sets of preprocessed entities.
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000463 for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000464 std::pair<FileID, unsigned> P
465 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
Douglas Gregorf88e35b2010-11-30 06:16:57 +0000466
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000467 ByFileMap[P.first].push_back(*E);
468 }
469 }
470
471 return std::make_pair(ByFileMap[Begin.first].begin(),
472 ByFileMap[Begin.first].end());
473}
474
Douglas Gregor71f3d942010-01-20 20:59:29 +0000475/// \brief Visit the children of the given cursor.
Ted Kremenek91554282010-11-16 08:15:36 +0000476///
Douglas Gregor71f3d942010-01-20 20:59:29 +0000477/// \returns true if the visitation should be aborted, false if it
478/// should continue.
Ted Kremenekf441baf2010-02-17 00:41:40 +0000479bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Douglas Gregor64f38ae2011-03-02 19:17:03 +0000480 if (clang_isReference(Cursor.kind) &&
481 Cursor.kind != CXCursor_CXXBaseSpecifier) {
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000482 // By definition, references have no children.
483 return false;
484 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000485
486 // Set the Parent field to Cursor, then back to its old value once we're
Douglas Gregor71f3d942010-01-20 20:59:29 +0000487 // done.
Ted Kremenek12e0f292010-05-13 00:25:00 +0000488 SetParentRAII SetParent(Parent, StmtParent, Cursor);
Ted Kremenekf441baf2010-02-17 00:41:40 +0000489
Douglas Gregor71f3d942010-01-20 20:59:29 +0000490 if (clang_isDeclaration(Cursor.kind)) {
491 Decl *D = getCursorDecl(Cursor);
492 assert(D && "Invalid declaration cursor");
Ted Kremenek0e293092010-02-18 18:47:01 +0000493 return VisitAttributes(D) || Visit(D);
Douglas Gregor71f3d942010-01-20 20:59:29 +0000494 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000495
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000496 if (clang_isStatement(Cursor.kind))
497 return Visit(getCursorStmt(Cursor));
498 if (clang_isExpression(Cursor.kind))
499 return Visit(getCursorExpr(Cursor));
Ted Kremenekf441baf2010-02-17 00:41:40 +0000500
Douglas Gregor71f3d942010-01-20 20:59:29 +0000501 if (clang_isTranslationUnit(Cursor.kind)) {
Ted Kremenek91554282010-11-16 08:15:36 +0000502 CXTranslationUnit tu = getCursorTU(Cursor);
503 ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
Douglas Gregor562c1f92010-01-22 19:49:59 +0000504 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
505 RegionOfInterest.isInvalid()) {
Douglas Gregore9db88f2010-08-03 19:06:41 +0000506 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
507 TLEnd = CXXUnit->top_level_end();
508 TL != TLEnd; ++TL) {
Ted Kremenek91554282010-11-16 08:15:36 +0000509 if (Visit(MakeCXCursor(*TL, tu), true))
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000510 return true;
511 }
Douglas Gregor5272e802010-03-19 05:22:59 +0000512 } else if (VisitDeclContext(
513 CXXUnit->getASTContext().getTranslationUnitDecl()))
514 return true;
Bob Wilson4f559a32010-03-19 03:57:57 +0000515
Douglas Gregor5272e802010-03-19 05:22:59 +0000516 // Walk the preprocessing record.
Daniel Dunbaraef1db12010-03-20 01:11:56 +0000517 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
Douglas Gregor5272e802010-03-19 05:22:59 +0000518 // FIXME: Once we have the ability to deserialize a preprocessing record,
519 // do so.
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000520 PreprocessingRecord::iterator E, EEnd;
521 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
Douglas Gregor5272e802010-03-19 05:22:59 +0000522 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
Ted Kremenek91554282010-11-16 08:15:36 +0000523 if (Visit(MakeMacroInstantiationCursor(MI, tu)))
Douglas Gregor5272e802010-03-19 05:22:59 +0000524 return true;
Douglas Gregor3dc10b52010-03-20 00:41:21 +0000525
Douglas Gregor5272e802010-03-19 05:22:59 +0000526 continue;
527 }
528
529 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
Ted Kremenek91554282010-11-16 08:15:36 +0000530 if (Visit(MakeMacroDefinitionCursor(MD, tu)))
Douglas Gregor5272e802010-03-19 05:22:59 +0000531 return true;
532
533 continue;
534 }
Douglas Gregor796d76a2010-10-20 22:00:55 +0000535
536 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
Ted Kremenek91554282010-11-16 08:15:36 +0000537 if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
Douglas Gregor796d76a2010-10-20 22:00:55 +0000538 return true;
539
540 continue;
541 }
Douglas Gregor5272e802010-03-19 05:22:59 +0000542 }
543 }
Douglas Gregorbefc4a12010-01-20 21:13:59 +0000544 return false;
Douglas Gregor71f3d942010-01-20 20:59:29 +0000545 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000546
Douglas Gregor64f38ae2011-03-02 19:17:03 +0000547 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
548 if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
549 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
550 return Visit(BaseTSInfo->getTypeLoc());
551 }
552 }
553 }
554
Douglas Gregor71f3d942010-01-20 20:59:29 +0000555 // Nothing to visit at the moment.
Douglas Gregor71f3d942010-01-20 20:59:29 +0000556 return false;
557}
558
Ted Kremenek33b9a422010-04-11 21:47:37 +0000559bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
John McCalla3cecb62010-06-04 22:33:30 +0000560 if (Visit(B->getSignatureAsWritten()->getTypeLoc()))
561 return true;
Ted Kremenek33b9a422010-04-11 21:47:37 +0000562
Ted Kremenek60fe71a2010-07-22 11:30:19 +0000563 if (Stmt *Body = B->getBody())
564 return Visit(MakeCXCursor(Body, StmtParent, TU));
565
566 return false;
Ted Kremenek33b9a422010-04-11 21:47:37 +0000567}
568
Ted Kremenekd40a4392010-11-02 23:10:24 +0000569llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
570 if (RegionOfInterest.isValid()) {
Douglas Gregor29ee4222010-11-17 17:14:07 +0000571 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
Ted Kremenekd40a4392010-11-02 23:10:24 +0000572 if (Range.isInvalid())
573 return llvm::Optional<bool>();
Douglas Gregor29ee4222010-11-17 17:14:07 +0000574
Ted Kremenekd40a4392010-11-02 23:10:24 +0000575 switch (CompareRegionOfInterest(Range)) {
576 case RangeBefore:
577 // This declaration comes before the region of interest; skip it.
578 return llvm::Optional<bool>();
579
580 case RangeAfter:
581 // This declaration comes after the region of interest; we're done.
582 return false;
583
584 case RangeOverlap:
585 // This declaration overlaps the region of interest; visit it.
586 break;
587 }
588 }
589 return true;
590}
591
592bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
593 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
594
595 // FIXME: Eventually remove. This part of a hack to support proper
596 // iteration over all Decls contained lexically within an ObjC container.
597 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
598 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
599
600 for ( ; I != E; ++I) {
Ted Kremenek49be9e02010-05-18 21:09:07 +0000601 Decl *D = *I;
602 if (D->getLexicalDeclContext() != DC)
603 continue;
Ted Kremenek49be9e02010-05-18 21:09:07 +0000604 CXCursor Cursor = MakeCXCursor(D, TU);
Ted Kremenekd40a4392010-11-02 23:10:24 +0000605 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
606 if (!V.hasValue())
607 continue;
608 if (!V.getValue())
609 return false;
Daniel Dunbar02968e52010-02-14 10:02:57 +0000610 if (Visit(Cursor, true))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000611 return true;
612 }
Douglas Gregor71f3d942010-01-20 20:59:29 +0000613 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +0000614}
615
Douglas Gregord824f882010-01-22 00:50:27 +0000616bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
617 llvm_unreachable("Translation units are visited directly by Visit()");
618 return false;
619}
620
621bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
622 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
623 return Visit(TSInfo->getTypeLoc());
Ted Kremenekf441baf2010-02-17 00:41:40 +0000624
Douglas Gregord824f882010-01-22 00:50:27 +0000625 return false;
626}
627
628bool CursorVisitor::VisitTagDecl(TagDecl *D) {
629 return VisitDeclContext(D);
630}
631
Douglas Gregor9dc243c2010-09-01 17:32:36 +0000632bool CursorVisitor::VisitClassTemplateSpecializationDecl(
633 ClassTemplateSpecializationDecl *D) {
634 bool ShouldVisitBody = false;
635 switch (D->getSpecializationKind()) {
636 case TSK_Undeclared:
637 case TSK_ImplicitInstantiation:
638 // Nothing to visit
639 return false;
640
641 case TSK_ExplicitInstantiationDeclaration:
642 case TSK_ExplicitInstantiationDefinition:
643 break;
644
645 case TSK_ExplicitSpecialization:
646 ShouldVisitBody = true;
647 break;
648 }
649
650 // Visit the template arguments used in the specialization.
651 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
652 TypeLoc TL = SpecType->getTypeLoc();
653 if (TemplateSpecializationTypeLoc *TSTLoc
654 = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
655 for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
656 if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
657 return true;
658 }
659 }
660
661 if (ShouldVisitBody && VisitCXXRecordDecl(D))
662 return true;
663
664 return false;
665}
666
Douglas Gregorf96abb22010-08-31 19:31:58 +0000667bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
668 ClassTemplatePartialSpecializationDecl *D) {
669 // FIXME: Visit the "outer" template parameter lists on the TagDecl
670 // before visiting these template parameters.
671 if (VisitTemplateParameters(D->getTemplateParameters()))
672 return true;
673
674 // Visit the partial specialization arguments.
675 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
676 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
677 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
678 return true;
679
680 return VisitCXXRecordDecl(D);
681}
682
Douglas Gregor713602b2010-08-31 17:01:39 +0000683bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000684 // Visit the default argument.
685 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
686 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
687 if (Visit(DefArg->getTypeLoc()))
688 return true;
689
Douglas Gregor713602b2010-08-31 17:01:39 +0000690 return false;
691}
692
Douglas Gregord824f882010-01-22 00:50:27 +0000693bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
694 if (Expr *Init = D->getInitExpr())
695 return Visit(MakeCXCursor(Init, StmtParent, TU));
696 return false;
697}
698
Douglas Gregor93f89952010-01-21 16:28:34 +0000699bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
700 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
701 if (Visit(TSInfo->getTypeLoc()))
702 return true;
703
Douglas Gregor14454802011-02-25 02:25:35 +0000704 // Visit the nested-name-specifier, if present.
705 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
706 if (VisitNestedNameSpecifierLoc(QualifierLoc))
707 return true;
708
Douglas Gregor93f89952010-01-21 16:28:34 +0000709 return false;
710}
711
Douglas Gregorf3af3112010-09-09 21:42:20 +0000712/// \brief Compare two base or member initializers based on their source order.
Alexis Hunt1d792652011-01-08 20:30:50 +0000713static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
714 CXXCtorInitializer const * const *X
715 = static_cast<CXXCtorInitializer const * const *>(Xp);
716 CXXCtorInitializer const * const *Y
717 = static_cast<CXXCtorInitializer const * const *>(Yp);
Douglas Gregorf3af3112010-09-09 21:42:20 +0000718
719 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
720 return -1;
721 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
722 return 1;
723 else
724 return 0;
725}
726
Douglas Gregor71f3d942010-01-20 20:59:29 +0000727bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Douglas Gregor12bca222010-08-31 14:41:23 +0000728 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
729 // Visit the function declaration's syntactic components in the order
730 // written. This requires a bit of work.
Abramo Bagnara6d810632010-12-14 22:11:44 +0000731 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Douglas Gregor12bca222010-08-31 14:41:23 +0000732 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
733
734 // If we have a function declared directly (without the use of a typedef),
735 // visit just the return type. Otherwise, just visit the function's type
736 // now.
737 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
738 (!FTL && Visit(TL)))
739 return true;
740
Douglas Gregor3335f482010-09-02 17:35:32 +0000741 // Visit the nested-name-specifier, if present.
Douglas Gregor14454802011-02-25 02:25:35 +0000742 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
743 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +0000744 return true;
Douglas Gregor12bca222010-08-31 14:41:23 +0000745
746 // Visit the declaration name.
747 if (VisitDeclarationNameInfo(ND->getNameInfo()))
748 return true;
749
750 // FIXME: Visit explicitly-specified template arguments!
751
752 // Visit the function parameters, if we have a function type.
753 if (FTL && VisitFunctionTypeLoc(*FTL, true))
754 return true;
755
756 // FIXME: Attributes?
757 }
758
Douglas Gregorf3af3112010-09-09 21:42:20 +0000759 if (ND->isThisDeclarationADefinition()) {
760 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
761 // Find the initializers that were written in the source.
Alexis Hunt1d792652011-01-08 20:30:50 +0000762 llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Douglas Gregorf3af3112010-09-09 21:42:20 +0000763 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
764 IEnd = Constructor->init_end();
765 I != IEnd; ++I) {
766 if (!(*I)->isWritten())
767 continue;
768
769 WrittenInits.push_back(*I);
770 }
771
772 // Sort the initializers in source order
773 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
Alexis Hunt1d792652011-01-08 20:30:50 +0000774 &CompareCXXCtorInitializers);
Douglas Gregorf3af3112010-09-09 21:42:20 +0000775
776 // Visit the initializers in source order
777 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
Alexis Hunt1d792652011-01-08 20:30:50 +0000778 CXXCtorInitializer *Init = WrittenInits[I];
Francois Pichetd583da02010-12-04 09:14:42 +0000779 if (Init->isAnyMemberInitializer()) {
780 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
Douglas Gregorf3af3112010-09-09 21:42:20 +0000781 Init->getMemberLocation(), TU)))
782 return true;
783 } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
784 if (Visit(BaseInfo->getTypeLoc()))
785 return true;
786 }
787
788 // Visit the initializer value.
789 if (Expr *Initializer = Init->getInit())
790 if (Visit(MakeCXCursor(Initializer, ND, TU)))
791 return true;
792 }
793 }
794
795 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
796 return true;
797 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000798
Douglas Gregor71f3d942010-01-20 20:59:29 +0000799 return false;
800}
Ted Kremenek78668fd2010-01-13 00:22:49 +0000801
Douglas Gregord824f882010-01-22 00:50:27 +0000802bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
803 if (VisitDeclaratorDecl(D))
804 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000805
Douglas Gregord824f882010-01-22 00:50:27 +0000806 if (Expr *BitWidth = D->getBitWidth())
807 return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
Ted Kremenekf441baf2010-02-17 00:41:40 +0000808
Douglas Gregord824f882010-01-22 00:50:27 +0000809 return false;
810}
811
812bool CursorVisitor::VisitVarDecl(VarDecl *D) {
813 if (VisitDeclaratorDecl(D))
814 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000815
Douglas Gregord824f882010-01-22 00:50:27 +0000816 if (Expr *Init = D->getInit())
817 return Visit(MakeCXCursor(Init, StmtParent, TU));
Ted Kremenekf441baf2010-02-17 00:41:40 +0000818
Douglas Gregord824f882010-01-22 00:50:27 +0000819 return false;
820}
821
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000822bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
823 if (VisitDeclaratorDecl(D))
824 return true;
825
826 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
827 if (Expr *DefArg = D->getDefaultArgument())
828 return Visit(MakeCXCursor(DefArg, StmtParent, TU));
829
830 return false;
831}
832
Douglas Gregor713602b2010-08-31 17:01:39 +0000833bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
834 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
835 // before visiting these template parameters.
836 if (VisitTemplateParameters(D->getTemplateParameters()))
837 return true;
838
839 return VisitFunctionDecl(D->getTemplatedDecl());
840}
841
Douglas Gregor1fbaeb12010-08-31 19:02:00 +0000842bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
843 // FIXME: Visit the "outer" template parameter lists on the TagDecl
844 // before visiting these template parameters.
845 if (VisitTemplateParameters(D->getTemplateParameters()))
846 return true;
847
848 return VisitCXXRecordDecl(D->getTemplatedDecl());
849}
850
Douglas Gregor06c7d2d2010-09-01 20:16:53 +0000851bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
852 if (VisitTemplateParameters(D->getTemplateParameters()))
853 return true;
854
855 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
856 VisitTemplateArgumentLoc(D->getDefaultArgument()))
857 return true;
858
859 return false;
860}
861
Douglas Gregord824f882010-01-22 00:50:27 +0000862bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Douglas Gregor12852d92010-03-08 14:59:44 +0000863 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
864 if (Visit(TSInfo->getTypeLoc()))
865 return true;
866
Ted Kremenekf441baf2010-02-17 00:41:40 +0000867 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
Douglas Gregord824f882010-01-22 00:50:27 +0000868 PEnd = ND->param_end();
869 P != PEnd; ++P) {
870 if (Visit(MakeCXCursor(*P, TU)))
871 return true;
872 }
Ted Kremenekf441baf2010-02-17 00:41:40 +0000873
Douglas Gregord824f882010-01-22 00:50:27 +0000874 if (ND->isThisDeclarationADefinition() &&
875 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
876 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000877
Douglas Gregord824f882010-01-22 00:50:27 +0000878 return false;
879}
880
Ted Kremenekd40a4392010-11-02 23:10:24 +0000881namespace {
882 struct ContainerDeclsSort {
883 SourceManager &SM;
884 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
885 bool operator()(Decl *A, Decl *B) {
886 SourceLocation L_A = A->getLocStart();
887 SourceLocation L_B = B->getLocStart();
888 assert(L_A.isValid() && L_B.isValid());
889 return SM.isBeforeInTranslationUnit(L_A, L_B);
890 }
891 };
892}
893
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000894bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
Ted Kremenekd40a4392010-11-02 23:10:24 +0000895 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
896 // an @implementation can lexically contain Decls that are not properly
897 // nested in the AST. When we identify such cases, we need to retrofit
898 // this nesting here.
899 if (!DI_current)
900 return VisitDeclContext(D);
901
902 // Scan the Decls that immediately come after the container
903 // in the current DeclContext. If any fall within the
904 // container's lexical region, stash them into a vector
905 // for later processing.
906 llvm::SmallVector<Decl *, 24> DeclsInContainer;
907 SourceLocation EndLoc = D->getSourceRange().getEnd();
Ted Kremenek91554282010-11-16 08:15:36 +0000908 SourceManager &SM = AU->getSourceManager();
Ted Kremenekd40a4392010-11-02 23:10:24 +0000909 if (EndLoc.isValid()) {
910 DeclContext::decl_iterator next = *DI_current;
911 while (++next != DE_current) {
912 Decl *D_next = *next;
913 if (!D_next)
914 break;
915 SourceLocation L = D_next->getLocStart();
916 if (!L.isValid())
917 break;
918 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
919 *DI_current = next;
920 DeclsInContainer.push_back(D_next);
921 continue;
922 }
923 break;
924 }
925 }
926
927 // The common case.
928 if (DeclsInContainer.empty())
929 return VisitDeclContext(D);
930
931 // Get all the Decls in the DeclContext, and sort them with the
932 // additional ones we've collected. Then visit them.
933 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
934 I!=E; ++I) {
935 Decl *subDecl = *I;
Ted Kremenek4bd4d752010-11-02 23:17:51 +0000936 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
937 subDecl->getLocStart().isInvalid())
Ted Kremenekd40a4392010-11-02 23:10:24 +0000938 continue;
939 DeclsInContainer.push_back(subDecl);
940 }
941
942 // Now sort the Decls so that they appear in lexical order.
943 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
944 ContainerDeclsSort(SM));
945
946 // Now visit the decls.
947 for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
948 E = DeclsInContainer.end(); I != E; ++I) {
949 CXCursor Cursor = MakeCXCursor(*I, TU);
950 const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
951 if (!V.hasValue())
952 continue;
953 if (!V.getValue())
954 return false;
955 if (Visit(Cursor, true))
956 return true;
957 }
958 return false;
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000959}
960
Douglas Gregor71f3d942010-01-20 20:59:29 +0000961bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
Douglas Gregorfed36b12010-01-20 23:57:43 +0000962 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
963 TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000964 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000965
Douglas Gregoref6eb842010-01-16 15:44:18 +0000966 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
967 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
968 E = ND->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +0000969 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +0000970 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000971
Douglas Gregor5e8cf372010-01-21 23:27:09 +0000972 return VisitObjCContainerDecl(ND);
Ted Kremenek78668fd2010-01-13 00:22:49 +0000973}
974
Douglas Gregord824f882010-01-22 00:50:27 +0000975bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
976 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
977 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
978 E = PID->protocol_end(); I != E; ++I, ++PL)
979 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
980 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +0000981
Douglas Gregord824f882010-01-22 00:50:27 +0000982 return VisitObjCContainerDecl(PID);
983}
984
Ted Kremenek49be9e02010-05-18 21:09:07 +0000985bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
Douglas Gregor9f0e1aa2010-09-09 17:09:21 +0000986 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
John McCalla3cecb62010-06-04 22:33:30 +0000987 return true;
988
Ted Kremenek49be9e02010-05-18 21:09:07 +0000989 // FIXME: This implements a workaround with @property declarations also being
990 // installed in the DeclContext for the @interface. Eventually this code
991 // should be removed.
992 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
993 if (!CDecl || !CDecl->IsClassExtension())
994 return false;
995
996 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
997 if (!ID)
998 return false;
999
1000 IdentifierInfo *PropertyId = PD->getIdentifier();
1001 ObjCPropertyDecl *prevDecl =
1002 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1003
1004 if (!prevDecl)
1005 return false;
1006
1007 // Visit synthesized methods since they will be skipped when visiting
1008 // the @interface.
1009 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
Ted Kremenek2f075632010-09-21 20:52:59 +00001010 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek49be9e02010-05-18 21:09:07 +00001011 if (Visit(MakeCXCursor(MD, TU)))
1012 return true;
1013
1014 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
Ted Kremenek2f075632010-09-21 20:52:59 +00001015 if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
Ted Kremenek49be9e02010-05-18 21:09:07 +00001016 if (Visit(MakeCXCursor(MD, TU)))
1017 return true;
1018
1019 return false;
1020}
1021
Douglas Gregor71f3d942010-01-20 20:59:29 +00001022bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Ted Kremenek78668fd2010-01-13 00:22:49 +00001023 // Issue callbacks for super class.
Douglas Gregor71f3d942010-01-20 20:59:29 +00001024 if (D->getSuperClass() &&
1025 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf441baf2010-02-17 00:41:40 +00001026 D->getSuperClassLoc(),
Douglas Gregorfed36b12010-01-20 23:57:43 +00001027 TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001028 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001029
Douglas Gregoref6eb842010-01-16 15:44:18 +00001030 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1031 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1032 E = D->protocol_end(); I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +00001033 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001034 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001035
Douglas Gregor5e8cf372010-01-21 23:27:09 +00001036 return VisitObjCContainerDecl(D);
Ted Kremenek78668fd2010-01-13 00:22:49 +00001037}
1038
Douglas Gregord824f882010-01-22 00:50:27 +00001039bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1040 return VisitObjCContainerDecl(D);
Ted Kremenek78668fd2010-01-13 00:22:49 +00001041}
1042
Douglas Gregord824f882010-01-22 00:50:27 +00001043bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Ted Kremeneke184ac52010-03-19 20:39:03 +00001044 // 'ID' could be null when dealing with invalid code.
1045 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1046 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1047 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001048
Douglas Gregord824f882010-01-22 00:50:27 +00001049 return VisitObjCImplDecl(D);
1050}
1051
1052bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1053#if 0
1054 // Issue callbacks for super class.
1055 // FIXME: No source location information!
1056 if (D->getSuperClass() &&
1057 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
Ted Kremenekf441baf2010-02-17 00:41:40 +00001058 D->getSuperClassLoc(),
Douglas Gregord824f882010-01-22 00:50:27 +00001059 TU)))
1060 return true;
1061#endif
Ted Kremenekf441baf2010-02-17 00:41:40 +00001062
Douglas Gregord824f882010-01-22 00:50:27 +00001063 return VisitObjCImplDecl(D);
1064}
1065
1066bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
1067 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1068 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
1069 E = D->protocol_end();
1070 I != E; ++I, ++PL)
Douglas Gregorfed36b12010-01-20 23:57:43 +00001071 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
Douglas Gregor71f3d942010-01-20 20:59:29 +00001072 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001073
1074 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +00001075}
1076
Douglas Gregord824f882010-01-22 00:50:27 +00001077bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
1078 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
1079 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
1080 return true;
Ted Kremenekf441baf2010-02-17 00:41:40 +00001081
Douglas Gregord824f882010-01-22 00:50:27 +00001082 return false;
Ted Kremenek78668fd2010-01-13 00:22:49 +00001083}
1084
Douglas Gregorb1b71e52010-11-17 01:03:52 +00001085bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1086 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1087 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1088
1089 return false;
1090}
1091
Ted Kremenekbd67fb22010-05-06 23:38:21 +00001092bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1093 return VisitDeclContext(D);
1094}
1095
Douglas Gregora89314e2010-08-31 23:48:11 +00001096bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001097 // Visit nested-name-specifier.
Douglas Gregorc05ba2e2011-02-25 17:08:07 +00001098 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1099 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001100 return true;
Douglas Gregora89314e2010-08-31 23:48:11 +00001101
1102 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1103 D->getTargetNameLoc(), TU));
1104}
1105
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001106bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001107 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001108 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1109 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001110 return true;
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001111 }
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001112
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001113 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1114 return true;
1115
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001116 return VisitDeclarationNameInfo(D->getNameInfo());
1117}
1118
Douglas Gregor01a430132010-09-01 03:07:18 +00001119bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001120 // Visit nested-name-specifier.
Douglas Gregor12441b32011-02-25 16:33:46 +00001121 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1122 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001123 return true;
Douglas Gregor01a430132010-09-01 03:07:18 +00001124
1125 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1126 D->getIdentLocation(), TU));
1127}
1128
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001129bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001130 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001131 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1132 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001133 return true;
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001134 }
Douglas Gregor3335f482010-09-02 17:35:32 +00001135
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001136 return VisitDeclarationNameInfo(D->getNameInfo());
1137}
1138
1139bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1140 UnresolvedUsingTypenameDecl *D) {
Douglas Gregor3335f482010-09-02 17:35:32 +00001141 // Visit nested-name-specifier.
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001142 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1143 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Douglas Gregor3335f482010-09-02 17:35:32 +00001144 return true;
1145
Douglas Gregora9aa29c2010-09-01 19:52:22 +00001146 return false;
1147}
1148
Douglas Gregor12bca222010-08-31 14:41:23 +00001149bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1150 switch (Name.getName().getNameKind()) {
1151 case clang::DeclarationName::Identifier:
1152 case clang::DeclarationName::CXXLiteralOperatorName:
1153 case clang::DeclarationName::CXXOperatorName:
1154 case clang::DeclarationName::CXXUsingDirective:
1155 return false;
1156
1157 case clang::DeclarationName::CXXConstructorName:
1158 case clang::DeclarationName::CXXDestructorName:
1159 case clang::DeclarationName::CXXConversionFunctionName:
1160 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1161 return Visit(TSInfo->getTypeLoc());
1162 return false;
1163
1164 case clang::DeclarationName::ObjCZeroArgSelector:
1165 case clang::DeclarationName::ObjCOneArgSelector:
1166 case clang::DeclarationName::ObjCMultiArgSelector:
1167 // FIXME: Per-identifier location info?
1168 return false;
1169 }
1170
1171 return false;
1172}
1173
Douglas Gregor3335f482010-09-02 17:35:32 +00001174bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1175 SourceRange Range) {
1176 // FIXME: This whole routine is a hack to work around the lack of proper
1177 // source information in nested-name-specifiers (PR5791). Since we do have
1178 // a beginning source location, we can visit the first component of the
1179 // nested-name-specifier, if it's a single-token component.
1180 if (!NNS)
1181 return false;
1182
1183 // Get the first component in the nested-name-specifier.
1184 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1185 NNS = Prefix;
1186
1187 switch (NNS->getKind()) {
1188 case NestedNameSpecifier::Namespace:
Douglas Gregor3335f482010-09-02 17:35:32 +00001189 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1190 TU));
1191
Douglas Gregor7b26ff92011-02-24 02:36:08 +00001192 case NestedNameSpecifier::NamespaceAlias:
1193 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1194 Range.getBegin(), TU));
1195
Douglas Gregor3335f482010-09-02 17:35:32 +00001196 case NestedNameSpecifier::TypeSpec: {
1197 // If the type has a form where we know that the beginning of the source
1198 // range matches up with a reference cursor. Visit the appropriate reference
1199 // cursor.
John McCall424cec92011-01-19 06:33:43 +00001200 const Type *T = NNS->getAsType();
Douglas Gregor3335f482010-09-02 17:35:32 +00001201 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1202 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1203 if (const TagType *Tag = dyn_cast<TagType>(T))
1204 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1205 if (const TemplateSpecializationType *TST
1206 = dyn_cast<TemplateSpecializationType>(T))
1207 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1208 break;
1209 }
1210
1211 case NestedNameSpecifier::TypeSpecWithTemplate:
1212 case NestedNameSpecifier::Global:
1213 case NestedNameSpecifier::Identifier:
1214 break;
1215 }
1216
1217 return false;
1218}
1219
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001220bool
1221CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1222 llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1223 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1224 Qualifiers.push_back(Qualifier);
1225
1226 while (!Qualifiers.empty()) {
1227 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1228 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1229 switch (NNS->getKind()) {
1230 case NestedNameSpecifier::Namespace:
1231 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
Douglas Gregor14454802011-02-25 02:25:35 +00001232 Q.getLocalBeginLoc(),
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001233 TU)))
1234 return true;
1235
1236 break;
1237
1238 case NestedNameSpecifier::NamespaceAlias:
1239 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Douglas Gregor14454802011-02-25 02:25:35 +00001240 Q.getLocalBeginLoc(),
Douglas Gregora9d87bc2011-02-25 00:36:19 +00001241 TU)))
1242 return true;
1243
1244 break;
1245
1246 case NestedNameSpecifier::TypeSpec:
1247 case NestedNameSpecifier::TypeSpecWithTemplate:
1248 if (Visit(Q.getTypeLoc()))
1249 return true;
1250
1251 break;
1252
1253 case NestedNameSpecifier::Global:
1254 case NestedNameSpecifier::Identifier:
1255 break;
1256 }
1257 }
1258
1259 return false;
1260}
1261
Douglas Gregor713602b2010-08-31 17:01:39 +00001262bool CursorVisitor::VisitTemplateParameters(
1263 const TemplateParameterList *Params) {
1264 if (!Params)
1265 return false;
1266
1267 for (TemplateParameterList::const_iterator P = Params->begin(),
1268 PEnd = Params->end();
1269 P != PEnd; ++P) {
1270 if (Visit(MakeCXCursor(*P, TU)))
1271 return true;
1272 }
1273
1274 return false;
1275}
1276
Douglas Gregora23e8f72010-08-31 20:37:03 +00001277bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1278 switch (Name.getKind()) {
1279 case TemplateName::Template:
1280 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1281
1282 case TemplateName::OverloadedTemplate:
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001283 // Visit the overloaded template set.
1284 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1285 return true;
1286
Douglas Gregora23e8f72010-08-31 20:37:03 +00001287 return false;
1288
1289 case TemplateName::DependentTemplate:
1290 // FIXME: Visit nested-name-specifier.
1291 return false;
1292
1293 case TemplateName::QualifiedTemplate:
1294 // FIXME: Visit nested-name-specifier.
1295 return Visit(MakeCursorTemplateRef(
1296 Name.getAsQualifiedTemplateName()->getDecl(),
1297 Loc, TU));
Douglas Gregor5590be02011-01-15 06:45:20 +00001298
1299 case TemplateName::SubstTemplateTemplateParmPack:
1300 return Visit(MakeCursorTemplateRef(
1301 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1302 Loc, TU));
Douglas Gregora23e8f72010-08-31 20:37:03 +00001303 }
1304
1305 return false;
1306}
1307
Douglas Gregor713602b2010-08-31 17:01:39 +00001308bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1309 switch (TAL.getArgument().getKind()) {
1310 case TemplateArgument::Null:
1311 case TemplateArgument::Integral:
Douglas Gregor0192c232010-12-20 16:52:59 +00001312 case TemplateArgument::Pack:
Douglas Gregor713602b2010-08-31 17:01:39 +00001313 return false;
1314
Douglas Gregor713602b2010-08-31 17:01:39 +00001315 case TemplateArgument::Type:
1316 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1317 return Visit(TSInfo->getTypeLoc());
1318 return false;
1319
1320 case TemplateArgument::Declaration:
1321 if (Expr *E = TAL.getSourceDeclExpression())
1322 return Visit(MakeCXCursor(E, StmtParent, TU));
1323 return false;
1324
1325 case TemplateArgument::Expression:
1326 if (Expr *E = TAL.getSourceExpression())
1327 return Visit(MakeCXCursor(E, StmtParent, TU));
1328 return false;
1329
1330 case TemplateArgument::Template:
Douglas Gregore4ff4b52011-01-05 18:58:31 +00001331 case TemplateArgument::TemplateExpansion:
Douglas Gregor9d802122011-03-02 17:09:35 +00001332 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1333 return true;
1334
Douglas Gregore4ff4b52011-01-05 18:58:31 +00001335 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Douglas Gregora23e8f72010-08-31 20:37:03 +00001336 TAL.getTemplateNameLoc());
Douglas Gregor713602b2010-08-31 17:01:39 +00001337 }
1338
1339 return false;
1340}
1341
Ted Kremenekb80cba52010-05-07 01:04:29 +00001342bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1343 return VisitDeclContext(D);
1344}
1345
Douglas Gregor12bca222010-08-31 14:41:23 +00001346bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1347 return Visit(TL.getUnqualifiedLoc());
1348}
1349
Douglas Gregord1824312010-01-21 17:29:07 +00001350bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
Ted Kremenek91554282010-11-16 08:15:36 +00001351 ASTContext &Context = AU->getASTContext();
Douglas Gregord1824312010-01-21 17:29:07 +00001352
1353 // Some builtin types (such as Objective-C's "id", "sel", and
1354 // "Class") have associated declarations. Create cursors for those.
1355 QualType VisitType;
1356 switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001357 case BuiltinType::Void:
Douglas Gregord1824312010-01-21 17:29:07 +00001358 case BuiltinType::Bool:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001359 case BuiltinType::Char_U:
1360 case BuiltinType::UChar:
Douglas Gregord1824312010-01-21 17:29:07 +00001361 case BuiltinType::Char16:
1362 case BuiltinType::Char32:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001363 case BuiltinType::UShort:
Douglas Gregord1824312010-01-21 17:29:07 +00001364 case BuiltinType::UInt:
1365 case BuiltinType::ULong:
1366 case BuiltinType::ULongLong:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001367 case BuiltinType::UInt128:
1368 case BuiltinType::Char_S:
1369 case BuiltinType::SChar:
Chris Lattnerad3467e2010-12-25 23:25:43 +00001370 case BuiltinType::WChar_U:
1371 case BuiltinType::WChar_S:
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001372 case BuiltinType::Short:
1373 case BuiltinType::Int:
1374 case BuiltinType::Long:
1375 case BuiltinType::LongLong:
1376 case BuiltinType::Int128:
1377 case BuiltinType::Float:
1378 case BuiltinType::Double:
1379 case BuiltinType::LongDouble:
1380 case BuiltinType::NullPtr:
1381 case BuiltinType::Overload:
1382 case BuiltinType::Dependent:
Douglas Gregord1824312010-01-21 17:29:07 +00001383 break;
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001384
Ted Kremenekfcb3db72010-02-18 18:52:18 +00001385 case BuiltinType::ObjCId:
1386 VisitType = Context.getObjCIdType();
1387 break;
Ted Kremenekaaaf2bf2010-02-18 22:32:43 +00001388
1389 case BuiltinType::ObjCClass:
1390 VisitType = Context.getObjCClassType();
1391 break;
1392
Douglas Gregord1824312010-01-21 17:29:07 +00001393 case BuiltinType::ObjCSel:
1394 VisitType = Context.getObjCSelType();
1395 break;
1396 }
1397
1398 if (!VisitType.isNull()) {
1399 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Ted Kremenekf441baf2010-02-17 00:41:40 +00001400 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
Douglas Gregord1824312010-01-21 17:29:07 +00001401 TU));
1402 }
1403
1404 return false;
1405}
1406
Douglas Gregor93f89952010-01-21 16:28:34 +00001407bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1408 return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU));
1409}
1410
Douglas Gregord1824312010-01-21 17:29:07 +00001411bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1412 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1413}
1414
1415bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1416 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1417}
1418
Douglas Gregor713602b2010-08-31 17:01:39 +00001419bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00001420 // FIXME: We can't visit the template type parameter, because there's
Douglas Gregor713602b2010-08-31 17:01:39 +00001421 // no context information with which we can match up the depth/index in the
1422 // type to the appropriate
1423 return false;
1424}
1425
Douglas Gregord1824312010-01-21 17:29:07 +00001426bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1427 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1428 return true;
1429
John McCall8b07ec22010-05-15 11:32:37 +00001430 return false;
1431}
1432
1433bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1434 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1435 return true;
1436
Douglas Gregord1824312010-01-21 17:29:07 +00001437 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1438 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1439 TU)))
1440 return true;
1441 }
1442
1443 return false;
1444}
1445
1446bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
John McCall8b07ec22010-05-15 11:32:37 +00001447 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001448}
1449
Abramo Bagnara924a8f32010-12-10 16:29:40 +00001450bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1451 return Visit(TL.getInnerLoc());
1452}
1453
Douglas Gregord1824312010-01-21 17:29:07 +00001454bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1455 return Visit(TL.getPointeeLoc());
1456}
1457
1458bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1459 return Visit(TL.getPointeeLoc());
1460}
1461
1462bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1463 return Visit(TL.getPointeeLoc());
1464}
1465
1466bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00001467 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001468}
1469
1470bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00001471 return Visit(TL.getPointeeLoc());
Douglas Gregord1824312010-01-21 17:29:07 +00001472}
1473
Douglas Gregor12bca222010-08-31 14:41:23 +00001474bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1475 bool SkipResultType) {
1476 if (!SkipResultType && Visit(TL.getResultLoc()))
Douglas Gregord1824312010-01-21 17:29:07 +00001477 return true;
1478
Douglas Gregord1824312010-01-21 17:29:07 +00001479 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
Ted Kremenek6ca136a2010-04-07 00:27:13 +00001480 if (Decl *D = TL.getArg(I))
1481 if (Visit(MakeCXCursor(D, TU)))
1482 return true;
Douglas Gregord1824312010-01-21 17:29:07 +00001483
1484 return false;
1485}
1486
1487bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1488 if (Visit(TL.getElementLoc()))
1489 return true;
1490
1491 if (Expr *Size = TL.getSizeExpr())
1492 return Visit(MakeCXCursor(Size, StmtParent, TU));
1493
1494 return false;
1495}
1496
Douglas Gregor713602b2010-08-31 17:01:39 +00001497bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1498 TemplateSpecializationTypeLoc TL) {
Douglas Gregora23e8f72010-08-31 20:37:03 +00001499 // Visit the template name.
1500 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1501 TL.getTemplateNameLoc()))
1502 return true;
Douglas Gregor713602b2010-08-31 17:01:39 +00001503
1504 // Visit the template arguments.
1505 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1506 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1507 return true;
1508
1509 return false;
1510}
1511
Douglas Gregor6479fc42010-01-21 20:48:56 +00001512bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1513 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1514}
1515
1516bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1517 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1518 return Visit(TSInfo->getTypeLoc());
1519
1520 return false;
1521}
1522
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00001523bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1524 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1525 return true;
1526
1527 return false;
1528}
1529
Douglas Gregora7a795b2011-03-01 20:11:18 +00001530bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1531 DependentTemplateSpecializationTypeLoc TL) {
1532 // Visit the nested-name-specifier, if there is one.
1533 if (TL.getQualifierLoc() &&
1534 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1535 return true;
1536
1537 // Visit the template arguments.
1538 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1539 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1540 return true;
1541
1542 return false;
1543}
1544
Douglas Gregor844cb502011-03-01 18:12:44 +00001545bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1546 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1547 return true;
1548
1549 return Visit(TL.getNamedTypeLoc());
1550}
1551
Douglas Gregord2fa7662010-12-20 02:24:11 +00001552bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1553 return Visit(TL.getPatternLoc());
1554}
1555
Ted Kremenekae9e2212010-08-27 21:34:58 +00001556bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
Douglas Gregor14454802011-02-25 02:25:35 +00001557 // Visit the nested-name-specifier, if present.
1558 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1559 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1560 return true;
1561
Ted Kremenekae9e2212010-08-27 21:34:58 +00001562 if (D->isDefinition()) {
1563 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1564 E = D->bases_end(); I != E; ++I) {
1565 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1566 return true;
1567 }
1568 }
1569
1570 return VisitTagDecl(D);
1571}
1572
Ted Kremenek6ab9aa022010-02-18 05:46:33 +00001573bool CursorVisitor::VisitAttributes(Decl *D) {
Alexis Huntdcfba7b2010-08-18 23:23:40 +00001574 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1575 i != e; ++i)
1576 if (Visit(MakeCXCursor(*i, D, TU)))
Ted Kremenek6ab9aa022010-02-18 05:46:33 +00001577 return true;
1578
1579 return false;
1580}
1581
Ted Kremenek92209a42010-11-11 08:05:18 +00001582//===----------------------------------------------------------------------===//
1583// Data-recursive visitor methods.
1584//===----------------------------------------------------------------------===//
1585
Ted Kremenekacff73c2010-11-13 00:36:47 +00001586namespace {
Ted Kremenek072e6372010-11-13 00:36:50 +00001587#define DEF_JOB(NAME, DATA, KIND)\
1588class NAME : public VisitorJob {\
1589public:\
1590 NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1591 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Ted Kremenek83900272010-11-18 00:02:32 +00001592 DATA *get() const { return static_cast<DATA*>(data[0]); }\
Ted Kremenek072e6372010-11-13 00:36:50 +00001593};
1594
1595DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1596DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
Ted Kremenek573411b2010-11-13 00:58:18 +00001597DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
Ted Kremenek072e6372010-11-13 00:36:50 +00001598DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001599DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
1600 ExplicitTemplateArgsVisitKind)
Douglas Gregor557f05c2011-01-19 20:34:17 +00001601DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
Ted Kremenek072e6372010-11-13 00:36:50 +00001602#undef DEF_JOB
1603
1604class DeclVisit : public VisitorJob {
1605public:
1606 DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1607 VisitorJob(parent, VisitorJob::DeclVisitKind,
1608 d, isFirst ? (void*) 1 : (void*) 0) {}
1609 static bool classof(const VisitorJob *VJ) {
Ted Kremeneke6f03042010-11-15 22:23:26 +00001610 return VJ->getKind() == DeclVisitKind;
Ted Kremenek072e6372010-11-13 00:36:50 +00001611 }
Ted Kremenek83900272010-11-18 00:02:32 +00001612 Decl *get() const { return static_cast<Decl*>(data[0]); }
1613 bool isFirst() const { return data[1] ? true : false; }
Ted Kremenek072e6372010-11-13 00:36:50 +00001614};
Ted Kremenek072e6372010-11-13 00:36:50 +00001615class TypeLocVisit : public VisitorJob {
1616public:
1617 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1618 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1619 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1620
1621 static bool classof(const VisitorJob *VJ) {
1622 return VJ->getKind() == TypeLocVisitKind;
1623 }
1624
Ted Kremeneke6f03042010-11-15 22:23:26 +00001625 TypeLoc get() const {
Ted Kremenek83900272010-11-18 00:02:32 +00001626 QualType T = QualType::getFromOpaquePtr(data[0]);
1627 return TypeLoc(T, data[1]);
Ted Kremenek072e6372010-11-13 00:36:50 +00001628 }
1629};
1630
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001631class LabelRefVisit : public VisitorJob {
1632public:
Chris Lattnerc8e630e2011-02-17 07:39:24 +00001633 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1634 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001635 labelLoc.getPtrEncoding()) {}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001636
1637 static bool classof(const VisitorJob *VJ) {
1638 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1639 }
Chris Lattnerc8e630e2011-02-17 07:39:24 +00001640 LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001641 SourceLocation getLoc() const {
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001642 return SourceLocation::getFromPtrEncoding(data[1]); }
Ted Kremenek83900272010-11-18 00:02:32 +00001643};
1644class NestedNameSpecifierVisit : public VisitorJob {
1645public:
1646 NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
1647 CXCursor parent)
1648 : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001649 NS, R.getBegin().getPtrEncoding(),
1650 R.getEnd().getPtrEncoding()) {}
Ted Kremenek83900272010-11-18 00:02:32 +00001651 static bool classof(const VisitorJob *VJ) {
1652 return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
1653 }
1654 NestedNameSpecifier *get() const {
1655 return static_cast<NestedNameSpecifier*>(data[0]);
1656 }
1657 SourceRange getSourceRange() const {
1658 SourceLocation A =
1659 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1660 SourceLocation B =
1661 SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
1662 return SourceRange(A, B);
1663 }
1664};
Douglas Gregora6ce6082011-02-25 18:19:59 +00001665
1666class NestedNameSpecifierLocVisit : public VisitorJob {
1667public:
1668 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1669 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1670 Qualifier.getNestedNameSpecifier(),
1671 Qualifier.getOpaqueData()) { }
1672
1673 static bool classof(const VisitorJob *VJ) {
1674 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1675 }
1676
1677 NestedNameSpecifierLoc get() const {
1678 return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1679 data[1]);
1680 }
1681};
1682
Ted Kremenek83900272010-11-18 00:02:32 +00001683class DeclarationNameInfoVisit : public VisitorJob {
1684public:
1685 DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1686 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1687 static bool classof(const VisitorJob *VJ) {
1688 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1689 }
1690 DeclarationNameInfo get() const {
1691 Stmt *S = static_cast<Stmt*>(data[0]);
1692 switch (S->getStmtClass()) {
1693 default:
1694 llvm_unreachable("Unhandled Stmt");
1695 case Stmt::CXXDependentScopeMemberExprClass:
1696 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1697 case Stmt::DependentScopeDeclRefExprClass:
1698 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1699 }
1700 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001701};
Ted Kremenek5d304a32010-11-18 00:42:18 +00001702class MemberRefVisit : public VisitorJob {
1703public:
1704 MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1705 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
Jeffrey Yasskin8dfa5f12011-01-18 02:00:16 +00001706 L.getPtrEncoding()) {}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1709 }
1710 FieldDecl *get() const {
1711 return static_cast<FieldDecl*>(data[0]);
1712 }
1713 SourceLocation getLoc() const {
1714 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1715 }
1716};
Ted Kremenekacff73c2010-11-13 00:36:47 +00001717class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
1718 VisitorWorkList &WL;
1719 CXCursor Parent;
1720public:
1721 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1722 : WL(wl), Parent(parent) {}
1723
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001724 void VisitAddrLabelExpr(AddrLabelExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001725 void VisitBlockExpr(BlockExpr *B);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001726 void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Ted Kremenekfdc52372010-11-13 05:38:03 +00001727 void VisitCompoundStmt(CompoundStmt *S);
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001728 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
Ted Kremenek83900272010-11-18 00:02:32 +00001729 void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001730 void VisitCXXNewExpr(CXXNewExpr *E);
Ted Kremenek9f49b372010-11-17 02:18:35 +00001731 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001732 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001733 void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001734 void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Ted Kremeneka51cc432010-11-17 00:50:41 +00001735 void VisitCXXTypeidExpr(CXXTypeidExpr *E);
Ted Kremenek79ddc672010-11-17 00:50:36 +00001736 void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
Ted Kremenek7003a502010-11-17 00:50:52 +00001737 void VisitCXXUuidofExpr(CXXUuidofExpr *E);
Ted Kremenek573411b2010-11-13 00:58:18 +00001738 void VisitDeclRefExpr(DeclRefExpr *D);
Ted Kremenek072e6372010-11-13 00:36:50 +00001739 void VisitDeclStmt(DeclStmt *S);
Ted Kremenek83900272010-11-18 00:02:32 +00001740 void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001741 void VisitDesignatedInitExpr(DesignatedInitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001742 void VisitExplicitCastExpr(ExplicitCastExpr *E);
1743 void VisitForStmt(ForStmt *FS);
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001744 void VisitGotoStmt(GotoStmt *GS);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001745 void VisitIfStmt(IfStmt *If);
1746 void VisitInitListExpr(InitListExpr *IE);
1747 void VisitMemberExpr(MemberExpr *M);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001748 void VisitOffsetOfExpr(OffsetOfExpr *E);
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001749 void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001750 void VisitObjCMessageExpr(ObjCMessageExpr *M);
1751 void VisitOverloadExpr(OverloadExpr *E);
Ted Kremenek9f49b372010-11-17 02:18:35 +00001752 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001753 void VisitStmt(Stmt *S);
1754 void VisitSwitchStmt(SwitchStmt *S);
1755 void VisitWhileStmt(WhileStmt *W);
Ted Kremenek513cd572010-11-17 00:50:50 +00001756 void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00001757 void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001758 void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
Ted Kremenekc1c30cd2010-11-17 00:50:43 +00001759 void VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor557f05c2011-01-19 20:34:17 +00001760 void VisitSizeOfPackExpr(SizeOfPackExpr *E);
Douglas Gregor820ba7b2011-01-04 17:33:58 +00001761
Ted Kremenekacff73c2010-11-13 00:36:47 +00001762private:
Ted Kremenek83900272010-11-18 00:02:32 +00001763 void AddDeclarationNameInfo(Stmt *S);
1764 void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
Douglas Gregora6ce6082011-02-25 18:19:59 +00001765 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001766 void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001767 void AddMemberRef(FieldDecl *D, SourceLocation L);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001768 void AddStmt(Stmt *S);
Ted Kremenek072e6372010-11-13 00:36:50 +00001769 void AddDecl(Decl *D, bool isFirst = true);
Ted Kremenekacff73c2010-11-13 00:36:47 +00001770 void AddTypeLoc(TypeSourceInfo *TI);
1771 void EnqueueChildren(Stmt *S);
1772};
1773} // end anonyous namespace
1774
Ted Kremenek83900272010-11-18 00:02:32 +00001775void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1776 // 'S' should always be non-null, since it comes from the
1777 // statement we are visiting.
1778 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1779}
1780void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
1781 SourceRange R) {
1782 if (N)
1783 WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
1784}
Douglas Gregora6ce6082011-02-25 18:19:59 +00001785
1786void
1787EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1788 if (Qualifier)
1789 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1790}
1791
Ted Kremenekacff73c2010-11-13 00:36:47 +00001792void EnqueueVisitor::AddStmt(Stmt *S) {
1793 if (S)
1794 WL.push_back(StmtVisit(S, Parent));
1795}
Ted Kremenek072e6372010-11-13 00:36:50 +00001796void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00001797 if (D)
Ted Kremenek072e6372010-11-13 00:36:50 +00001798 WL.push_back(DeclVisit(D, Parent, isFirst));
Ted Kremenekacff73c2010-11-13 00:36:47 +00001799}
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001800void EnqueueVisitor::
1801 AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
1802 if (A)
1803 WL.push_back(ExplicitTemplateArgsVisit(
1804 const_cast<ExplicitTemplateArgumentList*>(A), Parent));
1805}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001806void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1807 if (D)
1808 WL.push_back(MemberRefVisit(D, L, Parent));
1809}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001810void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1811 if (TI)
1812 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1813 }
1814void EnqueueVisitor::EnqueueChildren(Stmt *S) {
Ted Kremenek6a5df572010-11-12 21:34:09 +00001815 unsigned size = WL.size();
John McCall8322c3a2011-02-13 04:07:26 +00001816 for (Stmt::child_range Child = S->children(); Child; ++Child) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00001817 AddStmt(*Child);
Ted Kremenek6a5df572010-11-12 21:34:09 +00001818 }
1819 if (size == WL.size())
1820 return;
1821 // Now reverse the entries we just added. This will match the DFS
1822 // ordering performed by the worklist.
1823 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1824 std::reverse(I, E);
1825}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001826void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1827 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1828}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001829void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
1830 AddDecl(B->getBlockDecl());
1831}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001832void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1833 EnqueueChildren(E);
1834 AddTypeLoc(E->getTypeSourceInfo());
1835}
Ted Kremenekfdc52372010-11-13 05:38:03 +00001836void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1837 for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1838 E = S->body_rend(); I != E; ++I) {
1839 AddStmt(*I);
1840 }
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001841}
Ted Kremenek83900272010-11-18 00:02:32 +00001842void EnqueueVisitor::
1843VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1844 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1845 AddDeclarationNameInfo(E);
Douglas Gregore16af532011-02-28 18:50:33 +00001846 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1847 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenek83900272010-11-18 00:02:32 +00001848 if (!E->isImplicitAccess())
1849 AddStmt(E->getBase());
1850}
Ted Kremenek89bad8a2010-11-13 05:55:53 +00001851void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
1852 // Enqueue the initializer or constructor arguments.
1853 for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
1854 AddStmt(E->getConstructorArg(I-1));
1855 // Enqueue the array size, if any.
1856 AddStmt(E->getArraySize());
1857 // Enqueue the allocated type.
1858 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1859 // Enqueue the placement arguments.
1860 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1861 AddStmt(E->getPlacementArg(I-1));
1862}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001863void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
Ted Kremenekbc8b3782010-11-13 05:55:56 +00001864 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1865 AddStmt(CE->getArg(I-1));
Ted Kremenekacff73c2010-11-13 00:36:47 +00001866 AddStmt(CE->getCallee());
1867 AddStmt(CE->getArg(0));
1868}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001869void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1870 // Visit the name of the type being destroyed.
1871 AddTypeLoc(E->getDestroyedTypeInfo());
1872 // Visit the scope type that looks disturbingly like the nested-name-specifier
1873 // but isn't.
1874 AddTypeLoc(E->getScopeTypeInfo());
1875 // Visit the nested-name-specifier.
Douglas Gregora6ce6082011-02-25 18:19:59 +00001876 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1877 AddNestedNameSpecifierLoc(QualifierLoc);
Ted Kremenek5d304a32010-11-18 00:42:18 +00001878 // Visit base expression.
1879 AddStmt(E->getBase());
1880}
Ted Kremenek9f49b372010-11-17 02:18:35 +00001881void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1882 AddTypeLoc(E->getTypeSourceInfo());
1883}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001884void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1885 EnqueueChildren(E);
1886 AddTypeLoc(E->getTypeSourceInfo());
1887}
Ted Kremeneka51cc432010-11-17 00:50:41 +00001888void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1889 EnqueueChildren(E);
1890 if (E->isTypeOperand())
1891 AddTypeLoc(E->getTypeOperandSourceInfo());
1892}
Ted Kremenek79ddc672010-11-17 00:50:36 +00001893
1894void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
1895 *E) {
1896 EnqueueChildren(E);
1897 AddTypeLoc(E->getTypeSourceInfo());
1898}
Ted Kremenek7003a502010-11-17 00:50:52 +00001899void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1900 EnqueueChildren(E);
1901 if (E->isTypeOperand())
1902 AddTypeLoc(E->getTypeOperandSourceInfo());
1903}
Ted Kremenek573411b2010-11-13 00:58:18 +00001904void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
Ted Kremenek8eaa1652010-11-17 00:50:47 +00001905 if (DR->hasExplicitTemplateArgs()) {
1906 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1907 }
Ted Kremenek573411b2010-11-13 00:58:18 +00001908 WL.push_back(DeclRefExprParts(DR, Parent));
1909}
Ted Kremenek83900272010-11-18 00:02:32 +00001910void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1911 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1912 AddDeclarationNameInfo(E);
Douglas Gregor3a43fd62011-02-25 20:49:16 +00001913 AddNestedNameSpecifierLoc(E->getQualifierLoc());
Ted Kremenek83900272010-11-18 00:02:32 +00001914}
Ted Kremenek072e6372010-11-13 00:36:50 +00001915void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1916 unsigned size = WL.size();
1917 bool isFirst = true;
1918 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1919 D != DEnd; ++D) {
1920 AddDecl(*D, isFirst);
1921 isFirst = false;
1922 }
1923 if (size == WL.size())
1924 return;
1925 // Now reverse the entries we just added. This will match the DFS
1926 // ordering performed by the worklist.
1927 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1928 std::reverse(I, E);
1929}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001930void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1931 AddStmt(E->getInit());
1932 typedef DesignatedInitExpr::Designator Designator;
1933 for (DesignatedInitExpr::reverse_designators_iterator
1934 D = E->designators_rbegin(), DEnd = E->designators_rend();
1935 D != DEnd; ++D) {
1936 if (D->isFieldDesignator()) {
1937 if (FieldDecl *Field = D->getField())
1938 AddMemberRef(Field, D->getFieldLoc());
1939 continue;
1940 }
1941 if (D->isArrayDesignator()) {
1942 AddStmt(E->getArrayIndex(*D));
1943 continue;
1944 }
1945 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1946 AddStmt(E->getArrayRangeEnd(*D));
1947 AddStmt(E->getArrayRangeStart(*D));
1948 }
1949}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001950void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1951 EnqueueChildren(E);
1952 AddTypeLoc(E->getTypeInfoAsWritten());
1953}
1954void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
1955 AddStmt(FS->getBody());
1956 AddStmt(FS->getInc());
1957 AddStmt(FS->getCond());
1958 AddDecl(FS->getConditionVariable());
1959 AddStmt(FS->getInit());
1960}
Ted Kremeneke48db8d2010-11-17 00:50:45 +00001961void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
1962 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
1963}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001964void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
1965 AddStmt(If->getElse());
1966 AddStmt(If->getThen());
1967 AddStmt(If->getCond());
1968 AddDecl(If->getConditionVariable());
1969}
1970void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
1971 // We care about the syntactic form of the initializer list, only.
1972 if (InitListExpr *Syntactic = IE->getSyntacticForm())
1973 IE = Syntactic;
1974 EnqueueChildren(IE);
1975}
1976void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
Douglas Gregor30313cb2010-11-17 17:15:08 +00001977 WL.push_back(MemberExprParts(M, Parent));
1978
1979 // If the base of the member access expression is an implicit 'this', don't
1980 // visit it.
1981 // FIXME: If we ever want to show these implicit accesses, this will be
1982 // unfortunate. However, clang_getCursor() relies on this behavior.
Douglas Gregor25b7e052011-03-02 21:06:53 +00001983 if (!M->isImplicitAccess())
1984 AddStmt(M->getBase());
Ted Kremenekacff73c2010-11-13 00:36:47 +00001985}
Ted Kremenek809c6fc2010-11-13 01:09:29 +00001986void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
1987 AddTypeLoc(E->getEncodedTypeSourceInfo());
1988}
Ted Kremenekacff73c2010-11-13 00:36:47 +00001989void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
1990 EnqueueChildren(M);
1991 AddTypeLoc(M->getClassReceiverTypeInfo());
1992}
Ted Kremenek5d304a32010-11-18 00:42:18 +00001993void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
1994 // Visit the components of the offsetof expression.
1995 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
1996 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
1997 const OffsetOfNode &Node = E->getComponent(I-1);
1998 switch (Node.getKind()) {
1999 case OffsetOfNode::Array:
2000 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2001 break;
2002 case OffsetOfNode::Field:
2003 AddMemberRef(Node.getField(), Node.getRange().getEnd());
2004 break;
2005 case OffsetOfNode::Identifier:
2006 case OffsetOfNode::Base:
2007 continue;
2008 }
2009 }
2010 // Visit the type into which we're computing the offset.
2011 AddTypeLoc(E->getTypeSourceInfo());
2012}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002013void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
Ted Kremenek8eaa1652010-11-17 00:50:47 +00002014 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002015 WL.push_back(OverloadExprParts(E, Parent));
2016}
Ted Kremenek9f49b372010-11-17 02:18:35 +00002017void EnqueueVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
2018 EnqueueChildren(E);
2019 if (E->isArgumentType())
2020 AddTypeLoc(E->getArgumentTypeInfo());
2021}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002022void EnqueueVisitor::VisitStmt(Stmt *S) {
2023 EnqueueChildren(S);
2024}
2025void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2026 AddStmt(S->getBody());
2027 AddStmt(S->getCond());
2028 AddDecl(S->getConditionVariable());
2029}
Ted Kremenekdd0d4b42010-11-17 00:50:39 +00002030
Ted Kremenekacff73c2010-11-13 00:36:47 +00002031void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2032 AddStmt(W->getBody());
2033 AddStmt(W->getCond());
2034 AddDecl(W->getConditionVariable());
2035}
Ted Kremenek513cd572010-11-17 00:50:50 +00002036void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2037 AddTypeLoc(E->getQueriedTypeSourceInfo());
2038}
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002039
2040void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002041 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichetcf7731b2010-12-08 09:11:05 +00002042 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002043}
2044
Ted Kremenekacff73c2010-11-13 00:36:47 +00002045void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2046 VisitOverloadExpr(U);
2047 if (!U->isImplicitAccess())
2048 AddStmt(U->getBase());
2049}
Ted Kremenekc1c30cd2010-11-17 00:50:43 +00002050void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2051 AddStmt(E->getSubExpr());
2052 AddTypeLoc(E->getWrittenTypeInfo());
2053}
Douglas Gregor557f05c2011-01-19 20:34:17 +00002054void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2055 WL.push_back(SizeOfPackExprParts(E, Parent));
2056}
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002057
Ted Kremenek92209a42010-11-11 08:05:18 +00002058void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00002059 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenek92209a42010-11-11 08:05:18 +00002060}
2061
2062bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2063 if (RegionOfInterest.isValid()) {
2064 SourceRange Range = getRawCursorExtent(C);
2065 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2066 return false;
2067 }
2068 return true;
2069}
2070
2071bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2072 while (!WL.empty()) {
2073 // Dequeue the worklist item.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002074 VisitorJob LI = WL.back();
2075 WL.pop_back();
2076
Ted Kremenek92209a42010-11-11 08:05:18 +00002077 // Set the Parent field, then back to its old value once we're done.
2078 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2079
2080 switch (LI.getKind()) {
Ted Kremenek73227d72010-11-12 18:26:56 +00002081 case VisitorJob::DeclVisitKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002082 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenek73227d72010-11-12 18:26:56 +00002083 if (!D)
2084 continue;
2085
2086 // For now, perform default visitation for Decls.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002087 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenek73227d72010-11-12 18:26:56 +00002088 return true;
2089
2090 continue;
2091 }
Ted Kremenek8eaa1652010-11-17 00:50:47 +00002092 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2093 const ExplicitTemplateArgumentList *ArgList =
2094 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2095 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2096 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2097 Arg != ArgEnd; ++Arg) {
2098 if (VisitTemplateArgumentLoc(*Arg))
2099 return true;
2100 }
2101 continue;
2102 }
Ted Kremeneke12bcf52010-11-12 21:34:12 +00002103 case VisitorJob::TypeLocVisitKind: {
2104 // Perform default visitation for TypeLocs.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002105 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremeneke12bcf52010-11-12 21:34:12 +00002106 return true;
2107 continue;
2108 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00002109 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerc8e630e2011-02-17 07:39:24 +00002110 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremenekc49211c2011-02-23 04:54:51 +00002111 if (LabelStmt *stmt = LS->getStmt()) {
2112 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2113 TU))) {
2114 return true;
2115 }
2116 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00002117 continue;
2118 }
Douglas Gregora6ce6082011-02-25 18:19:59 +00002119
Ted Kremenek83900272010-11-18 00:02:32 +00002120 case VisitorJob::NestedNameSpecifierVisitKind: {
2121 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2122 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2123 return true;
2124 continue;
2125 }
Douglas Gregora6ce6082011-02-25 18:19:59 +00002126
2127 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2128 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2129 if (VisitNestedNameSpecifierLoc(V->get()))
2130 return true;
2131 continue;
2132 }
2133
Ted Kremenek83900272010-11-18 00:02:32 +00002134 case VisitorJob::DeclarationNameInfoVisitKind: {
2135 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2136 ->get()))
2137 return true;
2138 continue;
2139 }
Ted Kremenek5d304a32010-11-18 00:42:18 +00002140 case VisitorJob::MemberRefVisitKind: {
2141 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2142 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2143 return true;
2144 continue;
2145 }
Ted Kremenek92209a42010-11-11 08:05:18 +00002146 case VisitorJob::StmtVisitKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002147 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek7716cd62010-11-11 23:11:43 +00002148 if (!S)
2149 continue;
2150
Ted Kremenek73227d72010-11-12 18:26:56 +00002151 // Update the current cursor.
Ted Kremenek92209a42010-11-11 08:05:18 +00002152 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenek5d304a32010-11-18 00:42:18 +00002153 if (!IsInRegionOfInterest(Cursor))
2154 continue;
2155 switch (Visitor(Cursor, Parent, ClientData)) {
2156 case CXChildVisit_Break: return true;
2157 case CXChildVisit_Continue: break;
2158 case CXChildVisit_Recurse:
2159 EnqueueWorkList(WL, S);
Ted Kremeneke6f03042010-11-15 22:23:26 +00002160 break;
Ted Kremenek92209a42010-11-11 08:05:18 +00002161 }
Ted Kremeneke6f03042010-11-15 22:23:26 +00002162 continue;
Ted Kremenek92209a42010-11-11 08:05:18 +00002163 }
2164 case VisitorJob::MemberExprPartsKind: {
2165 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002166 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenek92209a42010-11-11 08:05:18 +00002167
2168 // Visit the nested-name-specifier
Douglas Gregorea972d32011-02-28 21:54:11 +00002169 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek92209a42010-11-11 08:05:18 +00002171 return true;
2172
2173 // Visit the declaration name.
2174 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2175 return true;
2176
2177 // Visit the explicitly-specified template arguments, if any.
2178 if (M->hasExplicitTemplateArgs()) {
2179 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2180 *ArgEnd = Arg + M->getNumTemplateArgs();
2181 Arg != ArgEnd; ++Arg) {
2182 if (VisitTemplateArgumentLoc(*Arg))
2183 return true;
2184 }
2185 }
2186 continue;
2187 }
Ted Kremenek573411b2010-11-13 00:58:18 +00002188 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002189 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremenek573411b2010-11-13 00:58:18 +00002190 // Visit nested-name-specifier, if present.
Douglas Gregorea972d32011-02-28 21:54:11 +00002191 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2192 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek573411b2010-11-13 00:58:18 +00002193 return true;
2194 // Visit declaration name.
2195 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2196 return true;
Ted Kremenek573411b2010-11-13 00:58:18 +00002197 continue;
2198 }
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002199 case VisitorJob::OverloadExprPartsKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002200 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002201 // Visit the nested-name-specifier.
Douglas Gregor0da1d432011-02-28 20:01:57 +00002202 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2203 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002204 return true;
2205 // Visit the declaration name.
2206 if (VisitDeclarationNameInfo(O->getNameInfo()))
2207 return true;
2208 // Visit the overloaded declaration reference.
2209 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2210 return true;
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002211 continue;
2212 }
Douglas Gregor557f05c2011-01-19 20:34:17 +00002213 case VisitorJob::SizeOfPackExprPartsKind: {
2214 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2215 NamedDecl *Pack = E->getPack();
2216 if (isa<TemplateTypeParmDecl>(Pack)) {
2217 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2218 E->getPackLoc(), TU)))
2219 return true;
2220
2221 continue;
2222 }
2223
2224 if (isa<TemplateTemplateParmDecl>(Pack)) {
2225 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2226 E->getPackLoc(), TU)))
2227 return true;
2228
2229 continue;
2230 }
2231
2232 // Non-type template parameter packs and function parameter packs are
2233 // treated like DeclRefExpr cursors.
2234 continue;
2235 }
Ted Kremenek92209a42010-11-11 08:05:18 +00002236 }
2237 }
2238 return false;
2239}
2240
Ted Kremenek5d304a32010-11-18 00:42:18 +00002241bool CursorVisitor::Visit(Stmt *S) {
Ted Kremeneka4c27ec2010-11-15 23:31:32 +00002242 VisitorWorkList *WL = 0;
2243 if (!WorkListFreeList.empty()) {
2244 WL = WorkListFreeList.back();
2245 WL->clear();
2246 WorkListFreeList.pop_back();
2247 }
2248 else {
2249 WL = new VisitorWorkList();
2250 WorkListCache.push_back(WL);
2251 }
2252 EnqueueWorkList(*WL, S);
2253 bool result = RunVisitorWorkList(*WL);
2254 WorkListFreeList.push_back(WL);
2255 return result;
Ted Kremenek92209a42010-11-11 08:05:18 +00002256}
2257
2258//===----------------------------------------------------------------------===//
2259// Misc. API hooks.
2260//===----------------------------------------------------------------------===//
2261
Douglas Gregor2c844822010-09-24 21:18:36 +00002262static llvm::sys::Mutex EnableMultithreadingMutex;
2263static bool EnabledMultithreading;
2264
Benjamin Kramer61f5d0c2009-10-18 16:11:04 +00002265extern "C" {
Douglas Gregor1e21cc72010-02-18 23:07:20 +00002266CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2267 int displayDiagnostics) {
Daniel Dunbara5af410d2010-10-08 19:30:33 +00002268 // Disable pretty stack trace functionality, which will otherwise be a very
2269 // poor citizen of the world and set up all sorts of signal handlers.
2270 llvm::DisablePrettyStackTrace = true;
2271
Daniel Dunbarc91f2ff2010-08-18 18:43:14 +00002272 // We use crash recovery to make some of our APIs more reliable, implicitly
2273 // enable it.
2274 llvm::CrashRecoveryContext::Enable();
2275
Douglas Gregor2c844822010-09-24 21:18:36 +00002276 // Enable support for multithreading in LLVM.
2277 {
2278 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2279 if (!EnabledMultithreading) {
2280 llvm::llvm_start_multithreaded();
2281 EnabledMultithreading = true;
2282 }
2283 }
2284
Douglas Gregor87752492010-01-22 20:35:53 +00002285 CIndexer *CIdxr = new CIndexer();
Steve Naroff531e2842009-10-20 14:46:24 +00002286 if (excludeDeclarationsFromPCH)
2287 CIdxr->setOnlyLocalDecls();
Douglas Gregor1e21cc72010-02-18 23:07:20 +00002288 if (displayDiagnostics)
2289 CIdxr->setDisplayDiagnostics();
Steve Naroff531e2842009-10-20 14:46:24 +00002290 return CIdxr;
Steve Naroffd5e8e862009-08-27 19:51:58 +00002291}
2292
Daniel Dunbar079203f2009-12-01 03:14:51 +00002293void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002294 if (CIdx)
2295 delete static_cast<CIndexer *>(CIdx);
Steve Naroff3aa2d732009-09-17 18:33:27 +00002296}
2297
Daniel Dunbar079203f2009-12-01 03:14:51 +00002298CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002299 const char *ast_filename) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002300 if (!CIdx)
2301 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002302
Douglas Gregor16bef852009-10-16 20:01:17 +00002303 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis71731d62010-11-03 22:45:23 +00002304 FileSystemOptions FileSystemOpts;
2305 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002306
Douglas Gregor7f95d262010-04-05 23:52:57 +00002307 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremenek91554282010-11-16 08:15:36 +00002308 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002309 CXXIdx->getOnlyLocalDecls(),
2310 0, 0, true);
Ted Kremenek91554282010-11-16 08:15:36 +00002311 return MakeCXTranslationUnit(TU);
Steve Naroffd5e8e862009-08-27 19:51:58 +00002312}
2313
Douglas Gregor4a47bca2010-08-09 22:28:58 +00002314unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor176d2862010-09-27 05:49:58 +00002315 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregorf5a18542010-10-27 17:24:53 +00002316 CXTranslationUnit_CacheCompletionResults |
2317 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregor4a47bca2010-08-09 22:28:58 +00002318}
2319
Daniel Dunbar079203f2009-12-01 03:14:51 +00002320CXTranslationUnit
2321clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2322 const char *source_filename,
2323 int num_command_line_args,
Douglas Gregor57879fa2010-09-01 16:43:19 +00002324 const char * const *command_line_args,
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002325 unsigned num_unsaved_files,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002326 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor99d2cf42010-07-21 18:52:53 +00002327 return clang_parseTranslationUnit(CIdx, source_filename,
2328 command_line_args, num_command_line_args,
2329 unsaved_files, num_unsaved_files,
2330 CXTranslationUnit_DetailedPreprocessingRecord);
2331}
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002332
2333struct ParseTranslationUnitInfo {
2334 CXIndex CIdx;
2335 const char *source_filename;
Douglas Gregor57879fa2010-09-01 16:43:19 +00002336 const char *const *command_line_args;
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002337 int num_command_line_args;
2338 struct CXUnsavedFile *unsaved_files;
2339 unsigned num_unsaved_files;
2340 unsigned options;
2341 CXTranslationUnit result;
2342};
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002343static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002344 ParseTranslationUnitInfo *PTUI =
2345 static_cast<ParseTranslationUnitInfo*>(UserData);
2346 CXIndex CIdx = PTUI->CIdx;
2347 const char *source_filename = PTUI->source_filename;
Douglas Gregor57879fa2010-09-01 16:43:19 +00002348 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002349 int num_command_line_args = PTUI->num_command_line_args;
2350 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2351 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2352 unsigned options = PTUI->options;
2353 PTUI->result = 0;
Douglas Gregor99d2cf42010-07-21 18:52:53 +00002354
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002355 if (!CIdx)
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002356 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002357
Steve Naroff531e2842009-10-20 14:46:24 +00002358 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2359
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002360 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregor028d3e42010-08-09 20:45:32 +00002361 bool CompleteTranslationUnit
2362 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregorb14904c2010-08-13 22:48:40 +00002363 bool CacheCodeCompetionResults
2364 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregorf5a18542010-10-27 17:24:53 +00002365 bool CXXPrecompilePreamble
2366 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2367 bool CXXChainedPCH
2368 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregorb14904c2010-08-13 22:48:40 +00002369
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002370 // Configure the diagnostics.
2371 DiagnosticOptions DiagOpts;
Douglas Gregor7f95d262010-04-05 23:52:57 +00002372 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Douglas Gregor345c1bc2011-01-19 01:02:47 +00002373 Diags = CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2374 command_line_args);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002375
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002376 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2377 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattner58c79342010-04-05 22:42:27 +00002378 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002379 const llvm::MemoryBuffer *Buffer
Chris Lattner58c79342010-04-05 22:42:27 +00002380 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002381 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2382 Buffer));
2383 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00002384
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002385 llvm::SmallVector<const char *, 16> Args;
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002386
Ted Kremenek649bf5c2009-10-22 00:03:57 +00002387 // The 'source_filename' argument is optional. If the caller does not
2388 // specify it then it is assumed that the source file is specified
2389 // in the actual argument list.
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002390 if (source_filename)
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002391 Args.push_back(source_filename);
Douglas Gregor79edde82010-07-09 18:39:07 +00002392
2393 // Since the Clang C library is primarily used by batch tools dealing with
2394 // (often very broken) source code, where spell-checking can have a
2395 // significant negative impact on performance (particularly when
2396 // precompiled headers are involved), we disable it by default.
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002397 // Only do this if we haven't found a spell-checking-related argument.
2398 bool FoundSpellCheckingArgument = false;
2399 for (int I = 0; I != num_command_line_args; ++I) {
2400 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2401 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2402 FoundSpellCheckingArgument = true;
2403 break;
Steve Naroff531e2842009-10-20 14:46:24 +00002404 }
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002405 }
2406 if (!FoundSpellCheckingArgument)
2407 Args.push_back("-fno-spell-checking");
2408
2409 Args.insert(Args.end(), command_line_args,
2410 command_line_args + num_command_line_args);
Douglas Gregorac0605e2010-01-28 06:00:51 +00002411
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002412 // Do we need the detailed preprocessing record?
2413 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002414 Args.push_back("-Xclang");
2415 Args.push_back("-detailed-preprocessing-record");
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002416 }
2417
Argyrios Kyrtzidis8d5038c2010-11-18 21:47:04 +00002418 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002419 llvm::OwningPtr<ASTUnit> Unit(
2420 ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
2421 Diags,
2422 CXXIdx->getClangResourcesPath(),
2423 CXXIdx->getOnlyLocalDecls(),
Douglas Gregor44c6ee72010-11-11 00:39:14 +00002424 /*CaptureDiagnostics=*/true,
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002425 RemappedFiles.data(),
2426 RemappedFiles.size(),
Argyrios Kyrtzidis97d3a382011-03-08 23:35:24 +00002427 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002428 PrecompilePreamble,
2429 CompleteTranslationUnit,
Douglas Gregorf5a18542010-10-27 17:24:53 +00002430 CacheCodeCompetionResults,
2431 CXXPrecompilePreamble,
2432 CXXChainedPCH));
Ted Kremenekf441baf2010-02-17 00:41:40 +00002433
Argyrios Kyrtzidis8d5038c2010-11-18 21:47:04 +00002434 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002435 // Make sure to check that 'Unit' is non-NULL.
2436 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2437 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2438 DEnd = Unit->stored_diag_end();
2439 D != DEnd; ++D) {
2440 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2441 CXString Msg = clang_formatDiagnostic(&Diag,
2442 clang_defaultDiagnosticDisplayOptions());
2443 fprintf(stderr, "%s\n", clang_getCString(Msg));
2444 clang_disposeString(Msg);
2445 }
Douglas Gregord770f732010-02-22 23:17:23 +00002446#ifdef LLVM_ON_WIN32
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002447 // On Windows, force a flush, since there may be multiple copies of
2448 // stderr and stdout in the file system, all with different buffers
2449 // but writing to the same device.
2450 fflush(stderr);
2451#endif
2452 }
Douglas Gregor33cdd812010-02-18 18:08:43 +00002453 }
Douglas Gregorac0605e2010-01-28 06:00:51 +00002454
Ted Kremenek91554282010-11-16 08:15:36 +00002455 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002456}
2457CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2458 const char *source_filename,
Douglas Gregor57879fa2010-09-01 16:43:19 +00002459 const char * const *command_line_args,
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002460 int num_command_line_args,
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002461 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002462 unsigned num_unsaved_files,
2463 unsigned options) {
2464 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002465 num_command_line_args, unsaved_files,
2466 num_unsaved_files, options, 0 };
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002467 llvm::CrashRecoveryContext CRC;
2468
Daniel Dunbarb7383e62010-11-05 07:19:31 +00002469 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbarf10f9be2010-08-23 22:35:34 +00002470 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2471 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2472 fprintf(stderr, " 'command_line_args' : [");
2473 for (int i = 0; i != num_command_line_args; ++i) {
2474 if (i)
2475 fprintf(stderr, ", ");
2476 fprintf(stderr, "'%s'", command_line_args[i]);
2477 }
2478 fprintf(stderr, "],\n");
2479 fprintf(stderr, " 'unsaved_files' : [");
2480 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2481 if (i)
2482 fprintf(stderr, ", ");
2483 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2484 unsaved_files[i].Length);
2485 }
2486 fprintf(stderr, "],\n");
2487 fprintf(stderr, " 'options' : %d,\n", options);
2488 fprintf(stderr, "}\n");
2489
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002490 return 0;
2491 }
2492
2493 return PTUI.result;
Steve Naroff7781daa2009-10-15 20:04:39 +00002494}
2495
Douglas Gregor6bb92ec2010-08-13 15:35:05 +00002496unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2497 return CXSaveTranslationUnit_None;
2498}
2499
2500int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2501 unsigned options) {
Douglas Gregore9386682010-08-13 05:36:37 +00002502 if (!TU)
2503 return 1;
2504
Ted Kremenek91554282010-11-16 08:15:36 +00002505 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregore9386682010-08-13 05:36:37 +00002506}
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002507
Daniel Dunbar079203f2009-12-01 03:14:51 +00002508void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002509 if (CTUnit) {
2510 // If the translation unit has been marked as unsafe to free, just discard
2511 // it.
Ted Kremenek91554282010-11-16 08:15:36 +00002512 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002513 return;
2514
Ted Kremenek91554282010-11-16 08:15:36 +00002515 delete static_cast<ASTUnit *>(CTUnit->TUData);
2516 disposeCXStringPool(CTUnit->StringPool);
2517 delete CTUnit;
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002518 }
Steve Naroff3aa2d732009-09-17 18:33:27 +00002519}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002520
Douglas Gregorde051182010-08-11 15:58:42 +00002521unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2522 return CXReparse_None;
2523}
2524
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002525struct ReparseTranslationUnitInfo {
2526 CXTranslationUnit TU;
2527 unsigned num_unsaved_files;
2528 struct CXUnsavedFile *unsaved_files;
2529 unsigned options;
2530 int result;
2531};
Douglas Gregorca5b0532010-09-23 18:47:53 +00002532
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002533static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002534 ReparseTranslationUnitInfo *RTUI =
2535 static_cast<ReparseTranslationUnitInfo*>(UserData);
2536 CXTranslationUnit TU = RTUI->TU;
2537 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2538 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2539 unsigned options = RTUI->options;
2540 (void) options;
2541 RTUI->result = 1;
2542
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002543 if (!TU)
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002544 return;
Douglas Gregorca5b0532010-09-23 18:47:53 +00002545
Ted Kremenek91554282010-11-16 08:15:36 +00002546 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorca5b0532010-09-23 18:47:53 +00002547 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002548
2549 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2550 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2551 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2552 const llvm::MemoryBuffer *Buffer
Douglas Gregor8e984da2010-08-04 16:47:14 +00002553 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002554 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2555 Buffer));
2556 }
2557
Douglas Gregorca5b0532010-09-23 18:47:53 +00002558 if (!CXXUnit->Reparse(RemappedFiles.data(), RemappedFiles.size()))
2559 RTUI->result = 0;
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002560}
Douglas Gregorca5b0532010-09-23 18:47:53 +00002561
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002562int clang_reparseTranslationUnit(CXTranslationUnit TU,
2563 unsigned num_unsaved_files,
2564 struct CXUnsavedFile *unsaved_files,
2565 unsigned options) {
2566 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2567 options, 0 };
2568 llvm::CrashRecoveryContext CRC;
2569
Daniel Dunbarb7383e62010-11-05 07:19:31 +00002570 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002571 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremenek91554282010-11-16 08:15:36 +00002572 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002573 return 1;
2574 }
2575
Ted Kremenek55ccf4e2010-10-29 01:06:50 +00002576
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002577 return RTUI.result;
2578}
2579
Douglas Gregor028d3e42010-08-09 20:45:32 +00002580
Daniel Dunbar079203f2009-12-01 03:14:51 +00002581CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002582 if (!CTUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002583 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00002584
Ted Kremenek91554282010-11-16 08:15:36 +00002585 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002586 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroff38c1a7b2009-09-03 15:49:00 +00002587}
Daniel Dunbare58bd8b2009-08-28 16:30:07 +00002588
Douglas Gregord2fc7272010-01-20 00:23:15 +00002589CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00002590 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregord2fc7272010-01-20 00:23:15 +00002591 return Result;
2592}
2593
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002594} // end: extern "C"
Steve Naroffd5e8e862009-08-27 19:51:58 +00002595
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002596//===----------------------------------------------------------------------===//
Douglas Gregor4f46e782010-01-19 21:36:55 +00002597// CXSourceLocation and CXSourceRange Operations.
2598//===----------------------------------------------------------------------===//
2599
Douglas Gregor816fd362010-01-22 21:44:22 +00002600extern "C" {
2601CXSourceLocation clang_getNullLocation() {
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002602 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregor816fd362010-01-22 21:44:22 +00002603 return Result;
2604}
2605
2606unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar83a23542010-01-30 23:58:27 +00002607 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2608 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2609 loc1.int_data == loc2.int_data);
Douglas Gregor816fd362010-01-22 21:44:22 +00002610}
2611
2612CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2613 CXFile file,
2614 unsigned line,
2615 unsigned column) {
Douglas Gregor0925fbc2010-04-30 19:45:53 +00002616 if (!tu || !file)
Douglas Gregor816fd362010-01-22 21:44:22 +00002617 return clang_getNullLocation();
Douglas Gregor0925fbc2010-04-30 19:45:53 +00002618
Douglas Gregore6642762011-02-03 17:17:35 +00002619 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremenek91554282010-11-16 08:15:36 +00002620 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregore6642762011-02-03 17:17:35 +00002621 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregor816fd362010-01-22 21:44:22 +00002622 SourceLocation SLoc
Douglas Gregore6642762011-02-03 17:17:35 +00002623 = CXXUnit->getSourceManager().getLocation(File, line, column);
2624 if (SLoc.isInvalid()) {
2625 if (Logging)
2626 llvm::errs() << "clang_getLocation(\"" << File->getName()
2627 << "\", " << line << ", " << column << ") = invalid\n";
2628 return clang_getNullLocation();
2629 }
2630
2631 if (Logging)
2632 llvm::errs() << "clang_getLocation(\"" << File->getName()
2633 << "\", " << line << ", " << column << ") = "
2634 << SLoc.getRawEncoding() << "\n";
David Chisnall2e16ac52010-10-15 17:07:39 +00002635
2636 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2637}
2638
2639CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2640 CXFile file,
2641 unsigned offset) {
2642 if (!tu || !file)
2643 return clang_getNullLocation();
2644
Ted Kremenek91554282010-11-16 08:15:36 +00002645 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall2e16ac52010-10-15 17:07:39 +00002646 SourceLocation Start
2647 = CXXUnit->getSourceManager().getLocation(
2648 static_cast<const FileEntry *>(file),
2649 1, 1);
2650 if (Start.isInvalid()) return clang_getNullLocation();
2651
2652 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2653
2654 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002655
Ted Kremenek54140272010-06-28 23:54:17 +00002656 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregor816fd362010-01-22 21:44:22 +00002657}
2658
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002659CXSourceRange clang_getNullRange() {
2660 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2661 return Result;
2662}
Daniel Dunbar02968e52010-02-14 10:02:57 +00002663
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002664CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2665 if (begin.ptr_data[0] != end.ptr_data[0] ||
2666 begin.ptr_data[1] != end.ptr_data[1])
2667 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002668
2669 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002670 begin.int_data, end.int_data };
Douglas Gregor816fd362010-01-22 21:44:22 +00002671 return Result;
2672}
2673
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002674void clang_getInstantiationLocation(CXSourceLocation location,
2675 CXFile *file,
2676 unsigned *line,
2677 unsigned *column,
2678 unsigned *offset) {
Douglas Gregor4f46e782010-01-19 21:36:55 +00002679 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2680
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002681 if (!location.ptr_data[0] || Loc.isInvalid()) {
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002682 if (file)
2683 *file = 0;
2684 if (line)
2685 *line = 0;
2686 if (column)
2687 *column = 0;
2688 if (offset)
2689 *offset = 0;
2690 return;
2691 }
2692
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002693 const SourceManager &SM =
2694 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002695 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002696
2697 if (file)
2698 *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));
2699 if (line)
2700 *line = SM.getInstantiationLineNumber(InstLoc);
2701 if (column)
2702 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregor47751d62010-01-26 03:07:15 +00002703 if (offset)
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002704 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregor47751d62010-01-26 03:07:15 +00002705}
2706
Douglas Gregor229bebd2010-11-09 06:24:54 +00002707void clang_getSpellingLocation(CXSourceLocation location,
2708 CXFile *file,
2709 unsigned *line,
2710 unsigned *column,
2711 unsigned *offset) {
2712 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2713
2714 if (!location.ptr_data[0] || Loc.isInvalid()) {
2715 if (file)
2716 *file = 0;
2717 if (line)
2718 *line = 0;
2719 if (column)
2720 *column = 0;
2721 if (offset)
2722 *offset = 0;
2723 return;
2724 }
2725
2726 const SourceManager &SM =
2727 *static_cast<const SourceManager*>(location.ptr_data[0]);
2728 SourceLocation SpellLoc = Loc;
2729 if (SpellLoc.isMacroID()) {
2730 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2731 if (SimpleSpellingLoc.isFileID() &&
2732 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2733 SpellLoc = SimpleSpellingLoc;
2734 else
2735 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2736 }
2737
2738 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2739 FileID FID = LocInfo.first;
2740 unsigned FileOffset = LocInfo.second;
2741
2742 if (file)
2743 *file = (void *)SM.getFileEntryForID(FID);
2744 if (line)
2745 *line = SM.getLineNumber(FID, FileOffset);
2746 if (column)
2747 *column = SM.getColumnNumber(FID, FileOffset);
2748 if (offset)
2749 *offset = FileOffset;
2750}
2751
Douglas Gregor4f46e782010-01-19 21:36:55 +00002752CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002753 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002754 range.begin_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002755 return Result;
2756}
2757
2758CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002759 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002760 range.end_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002761 return Result;
2762}
2763
Douglas Gregor816fd362010-01-22 21:44:22 +00002764} // end: extern "C"
2765
Douglas Gregor4f46e782010-01-19 21:36:55 +00002766//===----------------------------------------------------------------------===//
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002767// CXFile Operations.
2768//===----------------------------------------------------------------------===//
2769
2770extern "C" {
Ted Kremenekc560b682010-02-17 00:41:20 +00002771CXString clang_getFileName(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002772 if (!SFile)
Ted Kremenek91554282010-11-16 08:15:36 +00002773 return createCXString((const char*)NULL);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002774
Steve Naroff6231f182009-10-27 14:35:18 +00002775 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenekc560b682010-02-17 00:41:20 +00002776 return createCXString(FEnt->getName());
Steve Naroff6231f182009-10-27 14:35:18 +00002777}
2778
2779time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002780 if (!SFile)
2781 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002782
Steve Naroff6231f182009-10-27 14:35:18 +00002783 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2784 return FEnt->getModificationTime();
Steve Naroff26760892009-09-25 21:45:39 +00002785}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002786
Douglas Gregor816fd362010-01-22 21:44:22 +00002787CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2788 if (!tu)
2789 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002790
Ted Kremenek91554282010-11-16 08:15:36 +00002791 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002792
Douglas Gregor816fd362010-01-22 21:44:22 +00002793 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner5159f612010-11-23 08:35:12 +00002794 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregor816fd362010-01-22 21:44:22 +00002795}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002796
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002797} // end: extern "C"
Steve Naroff26760892009-09-25 21:45:39 +00002798
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002799//===----------------------------------------------------------------------===//
2800// CXCursor Operations.
2801//===----------------------------------------------------------------------===//
2802
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002803static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregore6712982010-10-01 21:11:22 +00002804 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2805 return getDeclFromExpr(CE->getSubExpr());
2806
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002807 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2808 return RefExpr->getDecl();
Douglas Gregor263803a2010-10-22 22:24:08 +00002809 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2810 return RefExpr->getDecl();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002811 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2812 return ME->getMemberDecl();
2813 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2814 return RE->getDecl();
Douglas Gregore6712982010-10-01 21:11:22 +00002815 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCallb7bd14f2010-12-02 01:19:52 +00002816 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregore6712982010-10-01 21:11:22 +00002817
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002818 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2819 return getDeclFromExpr(CE->getCallee());
Douglas Gregor16443fd2010-11-05 21:11:19 +00002820 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2821 if (!CE->isElidable())
2822 return CE->getConstructor();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002823 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2824 return OME->getMethodDecl();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002825
Douglas Gregore6712982010-10-01 21:11:22 +00002826 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2827 return PE->getProtocol();
Douglas Gregorcdbc5392011-01-15 01:15:58 +00002828 if (SubstNonTypeTemplateParmPackExpr *NTTP
2829 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2830 return NTTP->getParameterPack();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002831 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2832 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2833 isa<ParmVarDecl>(SizeOfPack->getPack()))
2834 return SizeOfPack->getPack();
Douglas Gregore6712982010-10-01 21:11:22 +00002835
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002836 return 0;
2837}
2838
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002839static SourceLocation getLocationFromExpr(Expr *E) {
2840 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2841 return /*FIXME:*/Msg->getLeftLoc();
2842 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2843 return DRE->getLocation();
Douglas Gregor263803a2010-10-22 22:24:08 +00002844 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2845 return RefExpr->getLocation();
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002846 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2847 return Member->getMemberLoc();
2848 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2849 return Ivar->getLocation();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002850 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2851 return SizeOfPack->getPackLoc();
2852
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002853 return E->getLocStart();
2854}
2855
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002856extern "C" {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002857
2858unsigned clang_visitChildren(CXCursor parent,
Douglas Gregor71f3d942010-01-20 20:59:29 +00002859 CXCursorVisitor visitor,
2860 CXClientData client_data) {
Ted Kremenek91554282010-11-16 08:15:36 +00002861 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
2862 getCursorASTUnit(parent)->getMaxPCHLevel());
Douglas Gregor71f3d942010-01-20 20:59:29 +00002863 return CursorVis.VisitChildren(parent);
2864}
2865
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002866#ifndef __has_feature
2867#define __has_feature(x) 0
2868#endif
2869#if __has_feature(blocks)
2870typedef enum CXChildVisitResult
2871 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2872
2873static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2874 CXClientData client_data) {
2875 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2876 return block(cursor, parent);
2877}
2878#else
2879// If we are compiled with a compiler that doesn't have native blocks support,
2880// define and call the block manually, so the
2881typedef struct _CXChildVisitResult
2882{
2883 void *isa;
2884 int flags;
2885 int reserved;
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002886 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2887 CXCursor);
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002888} *CXCursorVisitorBlock;
2889
2890static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2891 CXClientData client_data) {
2892 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2893 return block->invoke(block, cursor, parent);
2894}
2895#endif
2896
2897
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002898unsigned clang_visitChildrenWithBlock(CXCursor parent,
2899 CXCursorVisitorBlock block) {
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002900 return clang_visitChildren(parent, visitWithBlock, block);
2901}
2902
Douglas Gregordd969c82010-01-20 21:45:58 +00002903static CXString getDeclSpelling(Decl *D) {
2904 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002905 if (!ND) {
2906 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2907 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2908 return createCXString(Property->getIdentifier()->getName());
2909
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002910 return createCXString("");
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002911 }
2912
Douglas Gregordd969c82010-01-20 21:45:58 +00002913 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002914 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf441baf2010-02-17 00:41:40 +00002915
Douglas Gregordd969c82010-01-20 21:45:58 +00002916 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2917 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2918 // and returns different names. NamedDecl returns the class name and
2919 // ObjCCategoryImplDecl returns the category name.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002920 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf441baf2010-02-17 00:41:40 +00002921
Douglas Gregor01a430132010-09-01 03:07:18 +00002922 if (isa<UsingDirectiveDecl>(D))
2923 return createCXString("");
2924
Ted Kremenek08de5c12010-05-19 21:51:10 +00002925 llvm::SmallString<1024> S;
2926 llvm::raw_svector_ostream os(S);
2927 ND->printName(os);
2928
2929 return createCXString(os.str());
Douglas Gregordd969c82010-01-20 21:45:58 +00002930}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002931
Daniel Dunbar079203f2009-12-01 03:14:51 +00002932CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregord2fc7272010-01-20 00:23:15 +00002933 if (clang_isTranslationUnit(C.kind))
Ted Kremenek91554282010-11-16 08:15:36 +00002934 return clang_getTranslationUnitSpelling(
2935 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregord2fc7272010-01-20 00:23:15 +00002936
Steve Naroff80a766b2009-09-02 18:26:48 +00002937 if (clang_isReference(C.kind)) {
2938 switch (C.kind) {
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00002939 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor6c8959b2010-01-16 14:00:32 +00002940 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002941 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00002942 }
2943 case CXCursor_ObjCClassRef: {
Douglas Gregor46d66142010-01-16 17:14:40 +00002944 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002945 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00002946 }
2947 case CXCursor_ObjCProtocolRef: {
Douglas Gregoref6eb842010-01-16 15:44:18 +00002948 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregor7ecd0202010-01-18 23:41:10 +00002949 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002950 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00002951 }
Ted Kremenekae9e2212010-08-27 21:34:58 +00002952 case CXCursor_CXXBaseSpecifier: {
2953 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
2954 return createCXString(B->getType().getAsString());
2955 }
Douglas Gregor93f89952010-01-21 16:28:34 +00002956 case CXCursor_TypeRef: {
2957 TypeDecl *Type = getCursorTypeRef(C).first;
2958 assert(Type && "Missing type decl");
2959
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002960 return createCXString(getCursorContext(C).getTypeDeclType(Type).
2961 getAsString());
Douglas Gregor93f89952010-01-21 16:28:34 +00002962 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00002963 case CXCursor_TemplateRef: {
2964 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregora89314e2010-08-31 23:48:11 +00002965 assert(Template && "Missing template decl");
Douglas Gregora23e8f72010-08-31 20:37:03 +00002966
2967 return createCXString(Template->getNameAsString());
2968 }
Douglas Gregora89314e2010-08-31 23:48:11 +00002969
2970 case CXCursor_NamespaceRef: {
2971 NamedDecl *NS = getCursorNamespaceRef(C).first;
2972 assert(NS && "Missing namespace decl");
2973
2974 return createCXString(NS->getNameAsString());
2975 }
Douglas Gregor93f89952010-01-21 16:28:34 +00002976
Douglas Gregorf3af3112010-09-09 21:42:20 +00002977 case CXCursor_MemberRef: {
2978 FieldDecl *Field = getCursorMemberRef(C).first;
2979 assert(Field && "Missing member decl");
2980
2981 return createCXString(Field->getNameAsString());
2982 }
2983
Douglas Gregora93ab662010-09-10 00:22:18 +00002984 case CXCursor_LabelRef: {
2985 LabelStmt *Label = getCursorLabelRef(C).first;
2986 assert(Label && "Missing label");
2987
Chris Lattnerc8e630e2011-02-17 07:39:24 +00002988 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00002989 }
2990
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00002991 case CXCursor_OverloadedDeclRef: {
2992 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
2993 if (Decl *D = Storage.dyn_cast<Decl *>()) {
2994 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
2995 return createCXString(ND->getNameAsString());
2996 return createCXString("");
2997 }
2998 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
2999 return createCXString(E->getName().getAsString());
3000 OverloadedTemplateStorage *Ovl
3001 = Storage.get<OverloadedTemplateStorage*>();
3002 if (Ovl->size() == 0)
3003 return createCXString("");
3004 return createCXString((*Ovl->begin())->getNameAsString());
3005 }
3006
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003007 default:
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003008 return createCXString("<not implemented>");
Steve Naroff80a766b2009-09-02 18:26:48 +00003009 }
3010 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003011
3012 if (clang_isExpression(C.kind)) {
3013 Decl *D = getDeclFromExpr(getCursorExpr(C));
3014 if (D)
Douglas Gregordd969c82010-01-20 21:45:58 +00003015 return getDeclSpelling(D);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003016 return createCXString("");
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003017 }
3018
Douglas Gregora93ab662010-09-10 00:22:18 +00003019 if (clang_isStatement(C.kind)) {
3020 Stmt *S = getCursorStmt(C);
3021 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003022 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00003023
3024 return createCXString("");
3025 }
3026
Douglas Gregor065f8d12010-03-18 17:52:52 +00003027 if (C.kind == CXCursor_MacroInstantiation)
3028 return createCXString(getCursorMacroInstantiation(C)->getName()
3029 ->getNameStart());
3030
Douglas Gregor06d6d322010-03-18 18:04:21 +00003031 if (C.kind == CXCursor_MacroDefinition)
3032 return createCXString(getCursorMacroDefinition(C)->getName()
3033 ->getNameStart());
3034
Douglas Gregor796d76a2010-10-20 22:00:55 +00003035 if (C.kind == CXCursor_InclusionDirective)
3036 return createCXString(getCursorInclusionDirective(C)->getFileName());
3037
Douglas Gregor5bce76c2010-01-25 16:56:17 +00003038 if (clang_isDeclaration(C.kind))
3039 return getDeclSpelling(getCursorDecl(C));
Ted Kremenek29004672010-02-17 00:41:32 +00003040
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003041 return createCXString("");
Steve Naroff80a766b2009-09-02 18:26:48 +00003042}
3043
Douglas Gregor97c75712010-10-02 22:49:11 +00003044CXString clang_getCursorDisplayName(CXCursor C) {
3045 if (!clang_isDeclaration(C.kind))
3046 return clang_getCursorSpelling(C);
3047
3048 Decl *D = getCursorDecl(C);
3049 if (!D)
3050 return createCXString("");
3051
3052 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3053 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3054 D = FunTmpl->getTemplatedDecl();
3055
3056 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3057 llvm::SmallString<64> Str;
3058 llvm::raw_svector_ostream OS(Str);
3059 OS << Function->getNameAsString();
3060 if (Function->getPrimaryTemplate())
3061 OS << "<>";
3062 OS << "(";
3063 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3064 if (I)
3065 OS << ", ";
3066 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3067 }
3068
3069 if (Function->isVariadic()) {
3070 if (Function->getNumParams())
3071 OS << ", ";
3072 OS << "...";
3073 }
3074 OS << ")";
3075 return createCXString(OS.str());
3076 }
3077
3078 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3079 llvm::SmallString<64> Str;
3080 llvm::raw_svector_ostream OS(Str);
3081 OS << ClassTemplate->getNameAsString();
3082 OS << "<";
3083 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3084 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3085 if (I)
3086 OS << ", ";
3087
3088 NamedDecl *Param = Params->getParam(I);
3089 if (Param->getIdentifier()) {
3090 OS << Param->getIdentifier()->getName();
3091 continue;
3092 }
3093
3094 // There is no parameter name, which makes this tricky. Try to come up
3095 // with something useful that isn't too long.
3096 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3097 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3098 else if (NonTypeTemplateParmDecl *NTTP
3099 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3100 OS << NTTP->getType().getAsString(Policy);
3101 else
3102 OS << "template<...> class";
3103 }
3104
3105 OS << ">";
3106 return createCXString(OS.str());
3107 }
3108
3109 if (ClassTemplateSpecializationDecl *ClassSpec
3110 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3111 // If the type was explicitly written, use that.
3112 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3113 return createCXString(TSInfo->getType().getAsString(Policy));
3114
3115 llvm::SmallString<64> Str;
3116 llvm::raw_svector_ostream OS(Str);
3117 OS << ClassSpec->getNameAsString();
3118 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor1ccc8412010-11-07 23:05:16 +00003119 ClassSpec->getTemplateArgs().data(),
3120 ClassSpec->getTemplateArgs().size(),
Douglas Gregor97c75712010-10-02 22:49:11 +00003121 Policy);
3122 return createCXString(OS.str());
3123 }
3124
3125 return clang_getCursorSpelling(C);
3126}
3127
Ted Kremenek29004672010-02-17 00:41:32 +00003128CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff1054e602009-08-31 00:59:03 +00003129 switch (Kind) {
Ted Kremenek29004672010-02-17 00:41:32 +00003130 case CXCursor_FunctionDecl:
3131 return createCXString("FunctionDecl");
3132 case CXCursor_TypedefDecl:
3133 return createCXString("TypedefDecl");
3134 case CXCursor_EnumDecl:
3135 return createCXString("EnumDecl");
3136 case CXCursor_EnumConstantDecl:
3137 return createCXString("EnumConstantDecl");
3138 case CXCursor_StructDecl:
3139 return createCXString("StructDecl");
3140 case CXCursor_UnionDecl:
3141 return createCXString("UnionDecl");
3142 case CXCursor_ClassDecl:
3143 return createCXString("ClassDecl");
3144 case CXCursor_FieldDecl:
3145 return createCXString("FieldDecl");
3146 case CXCursor_VarDecl:
3147 return createCXString("VarDecl");
3148 case CXCursor_ParmDecl:
3149 return createCXString("ParmDecl");
3150 case CXCursor_ObjCInterfaceDecl:
3151 return createCXString("ObjCInterfaceDecl");
3152 case CXCursor_ObjCCategoryDecl:
3153 return createCXString("ObjCCategoryDecl");
3154 case CXCursor_ObjCProtocolDecl:
3155 return createCXString("ObjCProtocolDecl");
3156 case CXCursor_ObjCPropertyDecl:
3157 return createCXString("ObjCPropertyDecl");
3158 case CXCursor_ObjCIvarDecl:
3159 return createCXString("ObjCIvarDecl");
3160 case CXCursor_ObjCInstanceMethodDecl:
3161 return createCXString("ObjCInstanceMethodDecl");
3162 case CXCursor_ObjCClassMethodDecl:
3163 return createCXString("ObjCClassMethodDecl");
3164 case CXCursor_ObjCImplementationDecl:
3165 return createCXString("ObjCImplementationDecl");
3166 case CXCursor_ObjCCategoryImplDecl:
3167 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek225b8e32010-04-13 23:39:06 +00003168 case CXCursor_CXXMethod:
3169 return createCXString("CXXMethod");
Ted Kremenek29004672010-02-17 00:41:32 +00003170 case CXCursor_UnexposedDecl:
3171 return createCXString("UnexposedDecl");
3172 case CXCursor_ObjCSuperClassRef:
3173 return createCXString("ObjCSuperClassRef");
3174 case CXCursor_ObjCProtocolRef:
3175 return createCXString("ObjCProtocolRef");
3176 case CXCursor_ObjCClassRef:
3177 return createCXString("ObjCClassRef");
3178 case CXCursor_TypeRef:
3179 return createCXString("TypeRef");
Douglas Gregora23e8f72010-08-31 20:37:03 +00003180 case CXCursor_TemplateRef:
3181 return createCXString("TemplateRef");
Douglas Gregora89314e2010-08-31 23:48:11 +00003182 case CXCursor_NamespaceRef:
3183 return createCXString("NamespaceRef");
Douglas Gregorf3af3112010-09-09 21:42:20 +00003184 case CXCursor_MemberRef:
3185 return createCXString("MemberRef");
Douglas Gregora93ab662010-09-10 00:22:18 +00003186 case CXCursor_LabelRef:
3187 return createCXString("LabelRef");
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003188 case CXCursor_OverloadedDeclRef:
3189 return createCXString("OverloadedDeclRef");
Ted Kremenek29004672010-02-17 00:41:32 +00003190 case CXCursor_UnexposedExpr:
3191 return createCXString("UnexposedExpr");
Ted Kremenek33b9a422010-04-11 21:47:37 +00003192 case CXCursor_BlockExpr:
3193 return createCXString("BlockExpr");
Ted Kremenek29004672010-02-17 00:41:32 +00003194 case CXCursor_DeclRefExpr:
3195 return createCXString("DeclRefExpr");
3196 case CXCursor_MemberRefExpr:
3197 return createCXString("MemberRefExpr");
3198 case CXCursor_CallExpr:
3199 return createCXString("CallExpr");
3200 case CXCursor_ObjCMessageExpr:
3201 return createCXString("ObjCMessageExpr");
3202 case CXCursor_UnexposedStmt:
3203 return createCXString("UnexposedStmt");
Douglas Gregora93ab662010-09-10 00:22:18 +00003204 case CXCursor_LabelStmt:
3205 return createCXString("LabelStmt");
Ted Kremenek29004672010-02-17 00:41:32 +00003206 case CXCursor_InvalidFile:
3207 return createCXString("InvalidFile");
Ted Kremenek00da3b92010-03-19 20:39:05 +00003208 case CXCursor_InvalidCode:
3209 return createCXString("InvalidCode");
Ted Kremenek29004672010-02-17 00:41:32 +00003210 case CXCursor_NoDeclFound:
3211 return createCXString("NoDeclFound");
3212 case CXCursor_NotImplemented:
3213 return createCXString("NotImplemented");
3214 case CXCursor_TranslationUnit:
3215 return createCXString("TranslationUnit");
Ted Kremenekbff31432010-02-18 03:09:07 +00003216 case CXCursor_UnexposedAttr:
3217 return createCXString("UnexposedAttr");
3218 case CXCursor_IBActionAttr:
3219 return createCXString("attribute(ibaction)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003220 case CXCursor_IBOutletAttr:
3221 return createCXString("attribute(iboutlet)");
Ted Kremenek26bde772010-05-19 17:38:06 +00003222 case CXCursor_IBOutletCollectionAttr:
3223 return createCXString("attribute(iboutletcollection)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003224 case CXCursor_PreprocessingDirective:
3225 return createCXString("preprocessing directive");
Douglas Gregor06d6d322010-03-18 18:04:21 +00003226 case CXCursor_MacroDefinition:
3227 return createCXString("macro definition");
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003228 case CXCursor_MacroInstantiation:
3229 return createCXString("macro instantiation");
Douglas Gregor796d76a2010-10-20 22:00:55 +00003230 case CXCursor_InclusionDirective:
3231 return createCXString("inclusion directive");
Ted Kremenekbd67fb22010-05-06 23:38:21 +00003232 case CXCursor_Namespace:
3233 return createCXString("Namespace");
Ted Kremenekb80cba52010-05-07 01:04:29 +00003234 case CXCursor_LinkageSpec:
3235 return createCXString("LinkageSpec");
Ted Kremenekae9e2212010-08-27 21:34:58 +00003236 case CXCursor_CXXBaseSpecifier:
3237 return createCXString("C++ base class specifier");
Douglas Gregor12bca222010-08-31 14:41:23 +00003238 case CXCursor_Constructor:
3239 return createCXString("CXXConstructor");
3240 case CXCursor_Destructor:
3241 return createCXString("CXXDestructor");
3242 case CXCursor_ConversionFunction:
3243 return createCXString("CXXConversion");
Douglas Gregor713602b2010-08-31 17:01:39 +00003244 case CXCursor_TemplateTypeParameter:
3245 return createCXString("TemplateTypeParameter");
3246 case CXCursor_NonTypeTemplateParameter:
3247 return createCXString("NonTypeTemplateParameter");
3248 case CXCursor_TemplateTemplateParameter:
3249 return createCXString("TemplateTemplateParameter");
3250 case CXCursor_FunctionTemplate:
3251 return createCXString("FunctionTemplate");
Douglas Gregor1fbaeb12010-08-31 19:02:00 +00003252 case CXCursor_ClassTemplate:
3253 return createCXString("ClassTemplate");
Douglas Gregorf96abb22010-08-31 19:31:58 +00003254 case CXCursor_ClassTemplatePartialSpecialization:
3255 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregora89314e2010-08-31 23:48:11 +00003256 case CXCursor_NamespaceAlias:
3257 return createCXString("NamespaceAlias");
Douglas Gregor01a430132010-09-01 03:07:18 +00003258 case CXCursor_UsingDirective:
3259 return createCXString("UsingDirective");
Douglas Gregora9aa29c2010-09-01 19:52:22 +00003260 case CXCursor_UsingDeclaration:
3261 return createCXString("UsingDeclaration");
Steve Naroff1054e602009-08-31 00:59:03 +00003262 }
Ted Kremenek29004672010-02-17 00:41:32 +00003263
Ted Kremenek4ba52632010-01-16 02:02:09 +00003264 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremenek91554282010-11-16 08:15:36 +00003265 return createCXString((const char*) 0);
Steve Naroffd5e8e862009-08-27 19:51:58 +00003266}
Steve Naroff1054e602009-08-31 00:59:03 +00003267
Ted Kremenek29004672010-02-17 00:41:32 +00003268enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3269 CXCursor parent,
Douglas Gregor562c1f92010-01-22 19:49:59 +00003270 CXClientData client_data) {
3271 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor16443fd2010-11-05 21:11:19 +00003272
3273 // If our current best cursor is the construction of a temporary object,
3274 // don't replace that cursor with a type reference, because we want
3275 // clang_getCursor() to point at the constructor.
3276 if (clang_isExpression(BestCursor->kind) &&
3277 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3278 cursor.kind == CXCursor_TypeRef)
3279 return CXChildVisit_Recurse;
3280
Douglas Gregor3046b4d2010-12-10 07:23:11 +00003281 // Don't override a preprocessing cursor with another preprocessing
3282 // cursor; we want the outermost preprocessing cursor.
3283 if (clang_isPreprocessing(cursor.kind) &&
3284 clang_isPreprocessing(BestCursor->kind))
3285 return CXChildVisit_Recurse;
3286
Douglas Gregor562c1f92010-01-22 19:49:59 +00003287 *BestCursor = cursor;
3288 return CXChildVisit_Recurse;
3289}
Ted Kremenek29004672010-02-17 00:41:32 +00003290
Douglas Gregor816fd362010-01-22 21:44:22 +00003291CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3292 if (!TU)
Ted Kremeneke34cbde2010-01-14 01:51:23 +00003293 return clang_getNullCursor();
Ted Kremenek29004672010-02-17 00:41:32 +00003294
Ted Kremenek91554282010-11-16 08:15:36 +00003295 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00003296 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3297
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003298 // Translate the given source location to make it point at the beginning of
3299 // the token under the cursor.
Ted Kremenek97a45372010-01-25 22:34:44 +00003300 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremenek1e589f22010-07-29 00:52:07 +00003301
3302 // Guard against an invalid SourceLocation, or we may assert in one
3303 // of the following calls.
3304 if (SLoc.isInvalid())
3305 return clang_getNullCursor();
3306
Douglas Gregor15417cf2010-11-03 00:35:38 +00003307 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003308 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3309 CXXUnit->getASTContext().getLangOptions());
3310
Douglas Gregor562c1f92010-01-22 19:49:59 +00003311 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3312 if (SLoc.isValid()) {
Douglas Gregor562c1f92010-01-22 19:49:59 +00003313 // FIXME: Would be great to have a "hint" cursor, then walk from that
3314 // hint cursor upward until we find a cursor whose source range encloses
3315 // the region of interest, rather than starting from the translation unit.
Ted Kremenek91554282010-11-16 08:15:36 +00003316 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3317 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003318 Decl::MaxPCHLevel, SourceLocation(SLoc));
Douglas Gregor562c1f92010-01-22 19:49:59 +00003319 CursorVis.VisitChildren(Parent);
Steve Naroff54f22fb2009-09-15 20:25:34 +00003320 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003321
3322 if (Logging) {
3323 CXFile SearchFile;
3324 unsigned SearchLine, SearchColumn;
3325 CXFile ResultFile;
3326 unsigned ResultLine, ResultColumn;
Douglas Gregor29ee4222010-11-17 17:14:07 +00003327 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3328 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor15417cf2010-11-03 00:35:38 +00003329 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3330
3331 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3332 0);
3333 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3334 &ResultColumn, 0);
3335 SearchFileName = clang_getFileName(SearchFile);
3336 ResultFileName = clang_getFileName(ResultFile);
3337 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003338 USR = clang_getCursorUSR(Result);
3339 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor15417cf2010-11-03 00:35:38 +00003340 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3341 clang_getCString(KindSpelling),
Douglas Gregor29ee4222010-11-17 17:14:07 +00003342 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3343 clang_getCString(USR), IsDef);
Douglas Gregor15417cf2010-11-03 00:35:38 +00003344 clang_disposeString(SearchFileName);
3345 clang_disposeString(ResultFileName);
3346 clang_disposeString(KindSpelling);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003347 clang_disposeString(USR);
Douglas Gregor4a5bd5f2010-12-10 01:45:00 +00003348
3349 CXCursor Definition = clang_getCursorDefinition(Result);
3350 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3351 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3352 CXString DefinitionKindSpelling
3353 = clang_getCursorKindSpelling(Definition.kind);
3354 CXFile DefinitionFile;
3355 unsigned DefinitionLine, DefinitionColumn;
3356 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3357 &DefinitionLine, &DefinitionColumn, 0);
3358 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3359 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3360 clang_getCString(DefinitionKindSpelling),
3361 clang_getCString(DefinitionFileName),
3362 DefinitionLine, DefinitionColumn);
3363 clang_disposeString(DefinitionFileName);
3364 clang_disposeString(DefinitionKindSpelling);
3365 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003366 }
3367
Ted Kremenek29004672010-02-17 00:41:32 +00003368 return Result;
Steve Naroffd5e8e862009-08-27 19:51:58 +00003369}
3370
Ted Kremeneke05d7802009-11-17 19:28:59 +00003371CXCursor clang_getNullCursor(void) {
Douglas Gregor58552bc2010-01-20 23:34:41 +00003372 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremeneke05d7802009-11-17 19:28:59 +00003373}
3374
3375unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00003376 return X == Y;
Ted Kremeneke05d7802009-11-17 19:28:59 +00003377}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00003378
Douglas Gregor06a3f302010-11-20 00:09:34 +00003379unsigned clang_hashCursor(CXCursor C) {
3380 unsigned Index = 0;
3381 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3382 Index = 1;
3383
3384 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3385 std::make_pair(C.kind, C.data[Index]));
3386}
3387
Daniel Dunbar079203f2009-12-01 03:14:51 +00003388unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff54f22fb2009-09-15 20:25:34 +00003389 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3390}
3391
Daniel Dunbar079203f2009-12-01 03:14:51 +00003392unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff1054e602009-08-31 00:59:03 +00003393 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3394}
Steve Naroff772c1a42009-08-31 14:26:51 +00003395
Daniel Dunbar079203f2009-12-01 03:14:51 +00003396unsigned clang_isReference(enum CXCursorKind K) {
Steve Naroff80a766b2009-09-02 18:26:48 +00003397 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3398}
3399
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003400unsigned clang_isExpression(enum CXCursorKind K) {
3401 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3402}
3403
3404unsigned clang_isStatement(enum CXCursorKind K) {
3405 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3406}
3407
Douglas Gregord2fc7272010-01-20 00:23:15 +00003408unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3409 return K == CXCursor_TranslationUnit;
3410}
3411
Douglas Gregor92a524f2010-03-18 00:42:48 +00003412unsigned clang_isPreprocessing(enum CXCursorKind K) {
3413 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3414}
3415
Ted Kremenekff9021b2010-03-08 21:17:29 +00003416unsigned clang_isUnexposed(enum CXCursorKind K) {
3417 switch (K) {
3418 case CXCursor_UnexposedDecl:
3419 case CXCursor_UnexposedExpr:
3420 case CXCursor_UnexposedStmt:
3421 case CXCursor_UnexposedAttr:
3422 return true;
3423 default:
3424 return false;
3425 }
3426}
3427
Daniel Dunbar079203f2009-12-01 03:14:51 +00003428CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroffef9618b2009-09-04 15:44:05 +00003429 return C.kind;
3430}
3431
Douglas Gregor66a58812010-01-18 22:46:11 +00003432CXSourceLocation clang_getCursorLocation(CXCursor C) {
3433 if (clang_isReference(C.kind)) {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003434 switch (C.kind) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00003435 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003436 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3437 = getCursorObjCSuperClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003438 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003439 }
3440
Ted Kremenekf441baf2010-02-17 00:41:40 +00003441 case CXCursor_ObjCProtocolRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003442 std::pair<ObjCProtocolDecl *, SourceLocation> P
3443 = getCursorObjCProtocolRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003444 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003445 }
3446
Ted Kremenekf441baf2010-02-17 00:41:40 +00003447 case CXCursor_ObjCClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003448 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3449 = getCursorObjCClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003450 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003451 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003452
Ted Kremenekf441baf2010-02-17 00:41:40 +00003453 case CXCursor_TypeRef: {
Douglas Gregor93f89952010-01-21 16:28:34 +00003454 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003455 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor93f89952010-01-21 16:28:34 +00003456 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00003457
3458 case CXCursor_TemplateRef: {
3459 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3460 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3461 }
3462
Douglas Gregora89314e2010-08-31 23:48:11 +00003463 case CXCursor_NamespaceRef: {
3464 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3465 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3466 }
3467
Douglas Gregorf3af3112010-09-09 21:42:20 +00003468 case CXCursor_MemberRef: {
3469 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3470 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3471 }
3472
Ted Kremenekae9e2212010-08-27 21:34:58 +00003473 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor3478c752010-10-02 19:51:13 +00003474 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3475 if (!BaseSpec)
3476 return clang_getNullLocation();
3477
3478 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3479 return cxloc::translateSourceLocation(getCursorContext(C),
3480 TSInfo->getTypeLoc().getBeginLoc());
3481
3482 return cxloc::translateSourceLocation(getCursorContext(C),
3483 BaseSpec->getSourceRange().getBegin());
Ted Kremenekae9e2212010-08-27 21:34:58 +00003484 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003485
Douglas Gregora93ab662010-09-10 00:22:18 +00003486 case CXCursor_LabelRef: {
3487 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3488 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3489 }
3490
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003491 case CXCursor_OverloadedDeclRef:
3492 return cxloc::translateSourceLocation(getCursorContext(C),
3493 getCursorOverloadedDeclRef(C).second);
3494
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003495 default:
3496 // FIXME: Need a way to enumerate all non-reference cases.
3497 llvm_unreachable("Missed a reference kind");
3498 }
Douglas Gregor66a58812010-01-18 22:46:11 +00003499 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003500
3501 if (clang_isExpression(C.kind))
Ted Kremenekf441baf2010-02-17 00:41:40 +00003502 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003503 getLocationFromExpr(getCursorExpr(C)));
3504
Douglas Gregora93ab662010-09-10 00:22:18 +00003505 if (clang_isStatement(C.kind))
3506 return cxloc::translateSourceLocation(getCursorContext(C),
3507 getCursorStmt(C)->getLocStart());
3508
Douglas Gregor92a524f2010-03-18 00:42:48 +00003509 if (C.kind == CXCursor_PreprocessingDirective) {
3510 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3511 return cxloc::translateSourceLocation(getCursorContext(C), L);
3512 }
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003513
3514 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor065f8d12010-03-18 17:52:52 +00003515 SourceLocation L
3516 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003517 return cxloc::translateSourceLocation(getCursorContext(C), L);
3518 }
Douglas Gregor06d6d322010-03-18 18:04:21 +00003519
3520 if (C.kind == CXCursor_MacroDefinition) {
3521 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3522 return cxloc::translateSourceLocation(getCursorContext(C), L);
3523 }
Douglas Gregor796d76a2010-10-20 22:00:55 +00003524
3525 if (C.kind == CXCursor_InclusionDirective) {
3526 SourceLocation L
3527 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3528 return cxloc::translateSourceLocation(getCursorContext(C), L);
3529 }
3530
Ted Kremenek8278a322010-05-12 06:16:13 +00003531 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003532 return clang_getNullLocation();
Douglas Gregor66a58812010-01-18 22:46:11 +00003533
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003534 Decl *D = getCursorDecl(C);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003535 SourceLocation Loc = D->getLocation();
3536 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3537 Loc = Class->getClassLoc();
Ted Kremenek818e5c12010-11-01 23:26:51 +00003538 // FIXME: Multiple variables declared in a single declaration
3539 // currently lack the information needed to correctly determine their
3540 // ranges when accounting for the type-specifier. We use context
3541 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3542 // and if so, whether it is the first decl.
3543 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3544 if (!cxcursor::isFirstInDeclGroup(C))
3545 Loc = VD->getLocation();
3546 }
3547
Douglas Gregor7bf6b8a2010-03-22 15:53:50 +00003548 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor66a58812010-01-18 22:46:11 +00003549}
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003550
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003551} // end extern "C"
3552
3553static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003554 if (clang_isReference(C.kind)) {
3555 switch (C.kind) {
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003556 case CXCursor_ObjCSuperClassRef:
3557 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003558
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003559 case CXCursor_ObjCProtocolRef:
3560 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003561
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003562 case CXCursor_ObjCClassRef:
3563 return getCursorObjCClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003564
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003565 case CXCursor_TypeRef:
3566 return getCursorTypeRef(C).second;
Douglas Gregora23e8f72010-08-31 20:37:03 +00003567
3568 case CXCursor_TemplateRef:
3569 return getCursorTemplateRef(C).second;
3570
Douglas Gregora89314e2010-08-31 23:48:11 +00003571 case CXCursor_NamespaceRef:
3572 return getCursorNamespaceRef(C).second;
Douglas Gregorf3af3112010-09-09 21:42:20 +00003573
3574 case CXCursor_MemberRef:
3575 return getCursorMemberRef(C).second;
3576
Ted Kremenekae9e2212010-08-27 21:34:58 +00003577 case CXCursor_CXXBaseSpecifier:
Douglas Gregor3478c752010-10-02 19:51:13 +00003578 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor93f89952010-01-21 16:28:34 +00003579
Douglas Gregora93ab662010-09-10 00:22:18 +00003580 case CXCursor_LabelRef:
3581 return getCursorLabelRef(C).second;
3582
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003583 case CXCursor_OverloadedDeclRef:
3584 return getCursorOverloadedDeclRef(C).second;
3585
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003586 default:
3587 // FIXME: Need a way to enumerate all non-reference cases.
3588 llvm_unreachable("Missed a reference kind");
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003589 }
3590 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003591
3592 if (clang_isExpression(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003593 return getCursorExpr(C)->getSourceRange();
Douglas Gregor562c1f92010-01-22 19:49:59 +00003594
3595 if (clang_isStatement(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003596 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003597
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003598 if (C.kind == CXCursor_PreprocessingDirective)
3599 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003600
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003601 if (C.kind == CXCursor_MacroInstantiation)
3602 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor06d6d322010-03-18 18:04:21 +00003603
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003604 if (C.kind == CXCursor_MacroDefinition)
3605 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregor796d76a2010-10-20 22:00:55 +00003606
3607 if (C.kind == CXCursor_InclusionDirective)
3608 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3609
Ted Kremenek818e5c12010-11-01 23:26:51 +00003610 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3611 Decl *D = cxcursor::getCursorDecl(C);
3612 SourceRange R = D->getSourceRange();
3613 // FIXME: Multiple variables declared in a single declaration
3614 // currently lack the information needed to correctly determine their
3615 // ranges when accounting for the type-specifier. We use context
3616 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3617 // and if so, whether it is the first decl.
3618 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3619 if (!cxcursor::isFirstInDeclGroup(C))
3620 R.setBegin(VD->getLocation());
3621 }
3622 return R;
3623 }
Douglas Gregor29ee4222010-11-17 17:14:07 +00003624 return SourceRange();
3625}
3626
3627/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3628/// the decl-specifier-seq for declarations.
3629static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3630 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3631 Decl *D = cxcursor::getCursorDecl(C);
3632 SourceRange R = D->getSourceRange();
Douglas Gregor29ee4222010-11-17 17:14:07 +00003633
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00003634 // Adjust the start of the location for declarations preceded by
3635 // declaration specifiers.
3636 SourceLocation StartLoc;
3637 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3638 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3639 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3640 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3641 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3642 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3643 }
3644
3645 if (StartLoc.isValid() && R.getBegin().isValid() &&
3646 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3647 R.setBegin(StartLoc);
3648
3649 // FIXME: Multiple variables declared in a single declaration
3650 // currently lack the information needed to correctly determine their
3651 // ranges when accounting for the type-specifier. We use context
3652 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3653 // and if so, whether it is the first decl.
3654 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3655 if (!cxcursor::isFirstInDeclGroup(C))
3656 R.setBegin(VD->getLocation());
Douglas Gregor29ee4222010-11-17 17:14:07 +00003657 }
3658
3659 return R;
3660 }
3661
3662 return getRawCursorExtent(C);
3663}
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003664
3665extern "C" {
3666
3667CXSourceRange clang_getCursorExtent(CXCursor C) {
3668 SourceRange R = getRawCursorExtent(C);
3669 if (R.isInvalid())
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003670 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003671
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003672 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003673}
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003674
3675CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003676 if (clang_isInvalid(C.kind))
3677 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003678
Ted Kremenek91554282010-11-16 08:15:36 +00003679 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003680 if (clang_isDeclaration(C.kind)) {
3681 Decl *D = getCursorDecl(C);
3682 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003683 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003684 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003685 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003686 if (ObjCForwardProtocolDecl *Protocols
3687 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003688 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00003689 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3690 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3691 return MakeCXCursor(Property, tu);
3692
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003693 return C;
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003694 }
3695
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003696 if (clang_isExpression(C.kind)) {
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003697 Expr *E = getCursorExpr(C);
3698 Decl *D = getDeclFromExpr(E);
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003699 if (D)
Ted Kremenek91554282010-11-16 08:15:36 +00003700 return MakeCXCursor(D, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003701
3702 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremenek91554282010-11-16 08:15:36 +00003703 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003704
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003705 return clang_getNullCursor();
3706 }
3707
Douglas Gregora93ab662010-09-10 00:22:18 +00003708 if (clang_isStatement(C.kind)) {
3709 Stmt *S = getCursorStmt(C);
3710 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003711 return MakeCXCursor(Goto->getLabel()->getStmt(), getCursorDecl(C), tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003712
3713 return clang_getNullCursor();
3714 }
3715
Douglas Gregor78ae2482010-03-18 18:23:03 +00003716 if (C.kind == CXCursor_MacroInstantiation) {
3717 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003718 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregor78ae2482010-03-18 18:23:03 +00003719 }
3720
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003721 if (!clang_isReference(C.kind))
3722 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003723
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003724 switch (C.kind) {
3725 case CXCursor_ObjCSuperClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003726 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003727
3728 case CXCursor_ObjCProtocolRef: {
Ted Kremenek91554282010-11-16 08:15:36 +00003729 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003730
3731 case CXCursor_ObjCClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003732 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor93f89952010-01-21 16:28:34 +00003733
Ted Kremenekf441baf2010-02-17 00:41:40 +00003734 case CXCursor_TypeRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003735 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003736
3737 case CXCursor_TemplateRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003738 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003739
Douglas Gregora89314e2010-08-31 23:48:11 +00003740 case CXCursor_NamespaceRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003741 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregora89314e2010-08-31 23:48:11 +00003742
Douglas Gregorf3af3112010-09-09 21:42:20 +00003743 case CXCursor_MemberRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003744 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregorf3af3112010-09-09 21:42:20 +00003745
Ted Kremenekae9e2212010-08-27 21:34:58 +00003746 case CXCursor_CXXBaseSpecifier: {
3747 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3748 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremenek91554282010-11-16 08:15:36 +00003749 tu ));
Ted Kremenekae9e2212010-08-27 21:34:58 +00003750 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003751
Douglas Gregora93ab662010-09-10 00:22:18 +00003752 case CXCursor_LabelRef:
3753 // FIXME: We end up faking the "parent" declaration here because we
3754 // don't want to make CXCursor larger.
3755 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremenek91554282010-11-16 08:15:36 +00003756 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3757 .getTranslationUnitDecl(),
3758 tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003759
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003760 case CXCursor_OverloadedDeclRef:
3761 return C;
3762
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003763 default:
3764 // We would prefer to enumerate all non-reference cursor kinds here.
3765 llvm_unreachable("Unhandled reference cursor kind");
3766 break;
3767 }
3768 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003769
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003770 return clang_getNullCursor();
3771}
3772
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003773CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003774 if (clang_isInvalid(C.kind))
3775 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003776
Ted Kremenek91554282010-11-16 08:15:36 +00003777 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003778
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003779 bool WasReference = false;
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003780 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003781 C = clang_getCursorReferenced(C);
3782 WasReference = true;
3783 }
3784
Douglas Gregor78ae2482010-03-18 18:23:03 +00003785 if (C.kind == CXCursor_MacroInstantiation)
3786 return clang_getCursorReferenced(C);
3787
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003788 if (!clang_isDeclaration(C.kind))
3789 return clang_getNullCursor();
3790
3791 Decl *D = getCursorDecl(C);
3792 if (!D)
3793 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003794
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003795 switch (D->getKind()) {
3796 // Declaration kinds that don't really separate the notions of
3797 // declaration and definition.
3798 case Decl::Namespace:
3799 case Decl::Typedef:
3800 case Decl::TemplateTypeParm:
3801 case Decl::EnumConstant:
3802 case Decl::Field:
Benjamin Kramer39593702010-11-21 14:11:41 +00003803 case Decl::IndirectField:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003804 case Decl::ObjCIvar:
3805 case Decl::ObjCAtDefsField:
3806 case Decl::ImplicitParam:
3807 case Decl::ParmVar:
3808 case Decl::NonTypeTemplateParm:
3809 case Decl::TemplateTemplateParm:
3810 case Decl::ObjCCategoryImpl:
3811 case Decl::ObjCImplementation:
Abramo Bagnarad7340582010-06-05 05:09:32 +00003812 case Decl::AccessSpec:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003813 case Decl::LinkageSpec:
3814 case Decl::ObjCPropertyImpl:
3815 case Decl::FileScopeAsm:
3816 case Decl::StaticAssert:
3817 case Decl::Block:
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003818 case Decl::Label: // FIXME: Is this right??
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003819 return C;
3820
3821 // Declaration kinds that don't make any sense here, but are
3822 // nonetheless harmless.
3823 case Decl::TranslationUnit:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003824 break;
3825
3826 // Declaration kinds for which the definition is not resolvable.
3827 case Decl::UnresolvedUsingTypename:
3828 case Decl::UnresolvedUsingValue:
3829 break;
3830
3831 case Decl::UsingDirective:
Douglas Gregorfed36b12010-01-20 23:57:43 +00003832 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremenek91554282010-11-16 08:15:36 +00003833 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003834
3835 case Decl::NamespaceAlias:
Ted Kremenek91554282010-11-16 08:15:36 +00003836 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003837
3838 case Decl::Enum:
3839 case Decl::Record:
3840 case Decl::CXXRecord:
3841 case Decl::ClassTemplateSpecialization:
3842 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003843 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003844 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003845 return clang_getNullCursor();
3846
3847 case Decl::Function:
3848 case Decl::CXXMethod:
3849 case Decl::CXXConstructor:
3850 case Decl::CXXDestructor:
3851 case Decl::CXXConversion: {
3852 const FunctionDecl *Def = 0;
3853 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003854 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003855 return clang_getNullCursor();
3856 }
3857
3858 case Decl::Var: {
Sebastian Redl5ca79842010-02-01 20:16:42 +00003859 // Ask the variable if it has a definition.
3860 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003861 return MakeCXCursor(Def, TU);
Sebastian Redl5ca79842010-02-01 20:16:42 +00003862 return clang_getNullCursor();
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003863 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003864
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003865 case Decl::FunctionTemplate: {
3866 const FunctionDecl *Def = 0;
3867 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003868 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003869 return clang_getNullCursor();
3870 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003871
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003872 case Decl::ClassTemplate: {
3873 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003874 ->getDefinition())
Douglas Gregora23e8f72010-08-31 20:37:03 +00003875 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremenek91554282010-11-16 08:15:36 +00003876 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003877 return clang_getNullCursor();
3878 }
3879
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003880 case Decl::Using:
3881 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00003882 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003883
3884 case Decl::UsingShadow:
3885 return clang_getCursorDefinition(
Ted Kremenekf441baf2010-02-17 00:41:40 +00003886 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremenek91554282010-11-16 08:15:36 +00003887 TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003888
3889 case Decl::ObjCMethod: {
3890 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3891 if (Method->isThisDeclarationADefinition())
3892 return C;
3893
3894 // Dig out the method definition in the associated
3895 // @implementation, if we have it.
3896 // FIXME: The ASTs should make finding the definition easier.
3897 if (ObjCInterfaceDecl *Class
3898 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3899 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3900 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3901 Method->isInstanceMethod()))
3902 if (Def->isThisDeclarationADefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003903 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003904
3905 return clang_getNullCursor();
3906 }
3907
3908 case Decl::ObjCCategory:
3909 if (ObjCCategoryImplDecl *Impl
3910 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00003911 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003912 return clang_getNullCursor();
3913
3914 case Decl::ObjCProtocol:
3915 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3916 return C;
3917 return clang_getNullCursor();
3918
3919 case Decl::ObjCInterface:
3920 // There are two notions of a "definition" for an Objective-C
3921 // class: the interface and its implementation. When we resolved a
3922 // reference to an Objective-C class, produce the @interface as
3923 // the definition; when we were provided with the interface,
3924 // produce the @implementation as the definition.
3925 if (WasReference) {
3926 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
3927 return C;
3928 } else if (ObjCImplementationDecl *Impl
3929 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00003930 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003931 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003932
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003933 case Decl::ObjCProperty:
3934 // FIXME: We don't really know where to find the
3935 // ObjCPropertyImplDecls that implement this property.
3936 return clang_getNullCursor();
3937
3938 case Decl::ObjCCompatibleAlias:
3939 if (ObjCInterfaceDecl *Class
3940 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
3941 if (!Class->isForwardDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00003942 return MakeCXCursor(Class, TU);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003943
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003944 return clang_getNullCursor();
3945
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003946 case Decl::ObjCForwardProtocol:
3947 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00003948 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003949
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003950 case Decl::ObjCClass:
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00003951 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremenek91554282010-11-16 08:15:36 +00003952 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003953
3954 case Decl::Friend:
3955 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00003956 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003957 return clang_getNullCursor();
3958
3959 case Decl::FriendTemplate:
3960 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00003961 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003962 return clang_getNullCursor();
3963 }
3964
3965 return clang_getNullCursor();
3966}
3967
3968unsigned clang_isCursorDefinition(CXCursor C) {
3969 if (!clang_isDeclaration(C.kind))
3970 return 0;
3971
3972 return clang_getCursorDefinition(C) == C;
3973}
3974
Douglas Gregorfec4dc92010-11-19 23:44:15 +00003975CXCursor clang_getCanonicalCursor(CXCursor C) {
3976 if (!clang_isDeclaration(C.kind))
3977 return C;
3978
3979 if (Decl *D = getCursorDecl(C))
3980 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
3981
3982 return C;
3983}
3984
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003985unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregorae185302010-09-16 13:54:00 +00003986 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003987 return 0;
3988
3989 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3990 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3991 return E->getNumDecls();
3992
3993 if (OverloadedTemplateStorage *S
3994 = Storage.dyn_cast<OverloadedTemplateStorage*>())
3995 return S->size();
3996
3997 Decl *D = Storage.get<Decl*>();
3998 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis2703beb2010-11-10 05:40:41 +00003999 return Using->shadow_size();
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004000 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4001 return Classes->size();
4002 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4003 return Protocols->protocol_size();
4004
4005 return 0;
4006}
4007
4008CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregorae185302010-09-16 13:54:00 +00004009 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004010 return clang_getNullCursor();
4011
4012 if (index >= clang_getNumOverloadedDecls(cursor))
4013 return clang_getNullCursor();
4014
Ted Kremenek91554282010-11-16 08:15:36 +00004015 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004016 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4017 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremenek91554282010-11-16 08:15:36 +00004018 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004019
4020 if (OverloadedTemplateStorage *S
4021 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremenek91554282010-11-16 08:15:36 +00004022 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004023
4024 Decl *D = Storage.get<Decl*>();
4025 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4026 // FIXME: This is, unfortunately, linear time.
4027 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4028 std::advance(Pos, index);
Ted Kremenek91554282010-11-16 08:15:36 +00004029 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004030 }
4031
4032 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004033 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004034
4035 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004036 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004037
4038 return clang_getNullCursor();
4039}
4040
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00004041void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff76b8f132009-09-23 17:52:52 +00004042 const char **startBuf,
4043 const char **endBuf,
4044 unsigned *startLine,
4045 unsigned *startColumn,
4046 unsigned *endLine,
Daniel Dunbar079203f2009-12-01 03:14:51 +00004047 unsigned *endColumn) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00004048 assert(getCursorDecl(C) && "CXCursor has null decl");
4049 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff76b8f132009-09-23 17:52:52 +00004050 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4051 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004052
Steve Naroff76b8f132009-09-23 17:52:52 +00004053 SourceManager &SM = FD->getASTContext().getSourceManager();
4054 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4055 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4056 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4057 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4058 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4059 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4060}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004061
Douglas Gregor1e21cc72010-02-18 23:07:20 +00004062void clang_enableStackTraces(void) {
4063 llvm::sys::PrintStackTraceOnErrorSignal();
4064}
4065
Daniel Dunbar23420652010-11-04 01:26:29 +00004066void clang_executeOnThread(void (*fn)(void*), void *user_data,
4067 unsigned stack_size) {
4068 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4069}
4070
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004071} // end: extern "C"
Steve Naroff76b8f132009-09-23 17:52:52 +00004072
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004073//===----------------------------------------------------------------------===//
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004074// Token-based Operations.
4075//===----------------------------------------------------------------------===//
4076
4077/* CXToken layout:
4078 * int_data[0]: a CXTokenKind
4079 * int_data[1]: starting token location
4080 * int_data[2]: token length
4081 * int_data[3]: reserved
Ted Kremenekf441baf2010-02-17 00:41:40 +00004082 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004083 * otherwise unused.
4084 */
4085extern "C" {
4086
4087CXTokenKind clang_getTokenKind(CXToken CXTok) {
4088 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4089}
4090
4091CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4092 switch (clang_getTokenKind(CXTok)) {
4093 case CXToken_Identifier:
4094 case CXToken_Keyword:
4095 // We know we have an IdentifierInfo*, so use that.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004096 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4097 ->getNameStart());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004098
4099 case CXToken_Literal: {
4100 // We have stashed the starting pointer in the ptr_data field. Use it.
4101 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004102 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004103 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004104
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004105 case CXToken_Punctuation:
4106 case CXToken_Comment:
4107 break;
4108 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004109
4110 // We have to find the starting buffer pointer the hard way, by
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004111 // deconstructing the source location.
Ted Kremenek91554282010-11-16 08:15:36 +00004112 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004113 if (!CXXUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004114 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00004115
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004116 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4117 std::pair<FileID, unsigned> LocInfo
4118 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregore0fbb832010-03-16 00:06:06 +00004119 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004120 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004121 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4122 if (Invalid)
Douglas Gregor802b7762010-03-15 22:54:52 +00004123 return createCXString("");
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004124
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004125 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004126}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004127
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004128CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004129 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004130 if (!CXXUnit)
4131 return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004132
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004133 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4134 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4135}
4136
4137CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004138 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4f9c3762010-01-28 00:27:43 +00004139 if (!CXXUnit)
4140 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004141
4142 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004143 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4144}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004145
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004146void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4147 CXToken **Tokens, unsigned *NumTokens) {
4148 if (Tokens)
4149 *Tokens = 0;
4150 if (NumTokens)
4151 *NumTokens = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004152
Ted Kremenek91554282010-11-16 08:15:36 +00004153 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004154 if (!CXXUnit || !Tokens || !NumTokens)
4155 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004156
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004157 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4158
Daniel Dunbar80daf532010-02-14 08:31:57 +00004159 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004160 if (R.isInvalid())
4161 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004162
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004163 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4164 std::pair<FileID, unsigned> BeginLocInfo
4165 = SourceMgr.getDecomposedLoc(R.getBegin());
4166 std::pair<FileID, unsigned> EndLocInfo
4167 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004168
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004169 // Cannot tokenize across files.
4170 if (BeginLocInfo.first != EndLocInfo.first)
4171 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004172
4173 // Create a lexer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004174 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004175 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004176 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor554e0b12010-03-16 20:26:15 +00004177 if (Invalid)
4178 return;
Douglas Gregor802b7762010-03-15 22:54:52 +00004179
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004180 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4181 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004182 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004183 Lex.SetCommentRetentionState(true);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004184
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004185 // Lex tokens until we hit the end of the range.
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004186 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004187 llvm::SmallVector<CXToken, 32> CXTokens;
4188 Token Tok;
David Chisnall1822d1f2010-10-13 21:44:48 +00004189 bool previousWasAt = false;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004190 do {
4191 // Lex the next token
4192 Lex.LexFromRawLexer(Tok);
4193 if (Tok.is(tok::eof))
4194 break;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004195
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004196 // Initialize the CXToken.
4197 CXToken CXTok;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004198
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004199 // - Common fields
4200 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4201 CXTok.int_data[2] = Tok.getLength();
4202 CXTok.int_data[3] = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004203
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004204 // - Kind-specific fields
4205 if (Tok.isLiteral()) {
4206 CXTok.int_data[0] = CXToken_Literal;
4207 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004208 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregor802b7762010-03-15 22:54:52 +00004209 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004210 IdentifierInfo *II
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004211 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004212
David Chisnall1822d1f2010-10-13 21:44:48 +00004213 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004214 CXTok.int_data[0] = CXToken_Keyword;
4215 }
4216 else {
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004217 CXTok.int_data[0] = Tok.is(tok::identifier)
4218 ? CXToken_Identifier
4219 : CXToken_Keyword;
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004220 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004221 CXTok.ptr_data = II;
4222 } else if (Tok.is(tok::comment)) {
4223 CXTok.int_data[0] = CXToken_Comment;
4224 CXTok.ptr_data = 0;
4225 } else {
4226 CXTok.int_data[0] = CXToken_Punctuation;
4227 CXTok.ptr_data = 0;
4228 }
4229 CXTokens.push_back(CXTok);
David Chisnall1822d1f2010-10-13 21:44:48 +00004230 previousWasAt = Tok.is(tok::at);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004231 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004232
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004233 if (CXTokens.empty())
4234 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004235
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004236 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4237 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4238 *NumTokens = CXTokens.size();
4239}
Douglas Gregor61656112010-01-26 18:31:56 +00004240
Ted Kremenek63ac5992010-05-05 00:55:15 +00004241void clang_disposeTokens(CXTranslationUnit TU,
4242 CXToken *Tokens, unsigned NumTokens) {
4243 free(Tokens);
4244}
4245
4246} // end: extern "C"
4247
4248//===----------------------------------------------------------------------===//
4249// Token annotation APIs.
4250//===----------------------------------------------------------------------===//
4251
Douglas Gregor61656112010-01-26 18:31:56 +00004252typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenek680fe512010-05-05 00:55:23 +00004253static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4254 CXCursor parent,
4255 CXClientData client_data);
Ted Kremenek63ac5992010-05-05 00:55:15 +00004256namespace {
4257class AnnotateTokensWorker {
4258 AnnotateTokensData &Annotated;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004259 CXToken *Tokens;
4260 CXCursor *Cursors;
4261 unsigned NumTokens;
Ted Kremenek680fe512010-05-05 00:55:23 +00004262 unsigned TokIdx;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004263 unsigned PreprocessingTokIdx;
Ted Kremenek680fe512010-05-05 00:55:23 +00004264 CursorVisitor AnnotateVis;
4265 SourceManager &SrcMgr;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004266 bool HasContextSensitiveKeywords;
4267
Ted Kremenek680fe512010-05-05 00:55:23 +00004268 bool MoreTokens() const { return TokIdx < NumTokens; }
4269 unsigned NextToken() const { return TokIdx; }
4270 void AdvanceToken() { ++TokIdx; }
4271 SourceLocation GetTokenLoc(unsigned tokI) {
4272 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4273 }
4274
Ted Kremenek63ac5992010-05-05 00:55:15 +00004275public:
Ted Kremenek458c2f12010-05-05 00:55:17 +00004276 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenek680fe512010-05-05 00:55:23 +00004277 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremenek91554282010-11-16 08:15:36 +00004278 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek458c2f12010-05-05 00:55:17 +00004279 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004280 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremenek91554282010-11-16 08:15:36 +00004281 AnnotateVis(tu,
4282 AnnotateTokensVisitor, this,
Ted Kremenek680fe512010-05-05 00:55:23 +00004283 Decl::MaxPCHLevel, RegionOfInterest),
Douglas Gregorf2f08062011-03-08 17:10:18 +00004284 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4285 HasContextSensitiveKeywords(false) { }
Ted Kremenek458c2f12010-05-05 00:55:17 +00004286
Ted Kremenek680fe512010-05-05 00:55:23 +00004287 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004288 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenek680fe512010-05-05 00:55:23 +00004289 void AnnotateTokens(CXCursor parent);
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004290 void AnnotateTokens() {
Ted Kremenek91554282010-11-16 08:15:36 +00004291 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004292 }
Douglas Gregorf2f08062011-03-08 17:10:18 +00004293
4294 /// \brief Determine whether the annotator saw any cursors that have
4295 /// context-sensitive keywords.
4296 bool hasContextSensitiveKeywords() const {
4297 return HasContextSensitiveKeywords;
4298 }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004299};
4300}
Douglas Gregor61656112010-01-26 18:31:56 +00004301
Ted Kremenek680fe512010-05-05 00:55:23 +00004302void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4303 // Walk the AST within the region of interest, annotating tokens
4304 // along the way.
4305 VisitChildren(parent);
Ted Kremenek458c2f12010-05-05 00:55:17 +00004306
Ted Kremenek680fe512010-05-05 00:55:23 +00004307 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4308 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004309 if (Pos != Annotated.end() &&
4310 (clang_isInvalid(Cursors[I].kind) ||
4311 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenek680fe512010-05-05 00:55:23 +00004312 Cursors[I] = Pos->second;
4313 }
4314
4315 // Finish up annotating any tokens left.
4316 if (!MoreTokens())
4317 return;
4318
4319 const CXCursor &C = clang_getNullCursor();
4320 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4321 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4322 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004323 }
4324}
4325
Ted Kremenek63ac5992010-05-05 00:55:15 +00004326enum CXChildVisitResult
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004327AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004328 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004329 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004330 if (cursorRange.isInvalid())
4331 return CXChildVisit_Recurse;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004332
4333 if (!HasContextSensitiveKeywords) {
4334 // Objective-C properties can have context-sensitive keywords.
4335 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4336 if (ObjCPropertyDecl *Property
4337 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4338 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4339 }
4340 // Objective-C methods can have context-sensitive keywords.
4341 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4342 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4343 if (ObjCMethodDecl *Method
4344 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4345 if (Method->getObjCDeclQualifier())
4346 HasContextSensitiveKeywords = true;
4347 else {
4348 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4349 PEnd = Method->param_end();
4350 P != PEnd; ++P) {
4351 if ((*P)->getObjCDeclQualifier()) {
4352 HasContextSensitiveKeywords = true;
4353 break;
4354 }
4355 }
4356 }
4357 }
4358 }
4359 // C++ methods can have context-sensitive keywords.
4360 else if (cursor.kind == CXCursor_CXXMethod) {
4361 if (CXXMethodDecl *Method
4362 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4363 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4364 HasContextSensitiveKeywords = true;
4365 }
4366 }
4367 // C++ classes can have context-sensitive keywords.
4368 else if (cursor.kind == CXCursor_StructDecl ||
4369 cursor.kind == CXCursor_ClassDecl ||
4370 cursor.kind == CXCursor_ClassTemplate ||
4371 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4372 if (Decl *D = getCursorDecl(cursor))
4373 if (D->hasAttr<FinalAttr>())
4374 HasContextSensitiveKeywords = true;
4375 }
4376 }
4377
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004378 if (clang_isPreprocessing(cursor.kind)) {
4379 // For macro instantiations, just note where the beginning of the macro
4380 // instantiation occurs.
4381 if (cursor.kind == CXCursor_MacroInstantiation) {
4382 Annotated[Loc.int_data] = cursor;
4383 return CXChildVisit_Recurse;
4384 }
4385
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004386 // Items in the preprocessing record are kept separate from items in
4387 // declarations, so we keep a separate token index.
4388 unsigned SavedTokIdx = TokIdx;
4389 TokIdx = PreprocessingTokIdx;
4390
4391 // Skip tokens up until we catch up to the beginning of the preprocessing
4392 // entry.
4393 while (MoreTokens()) {
4394 const unsigned I = NextToken();
4395 SourceLocation TokLoc = GetTokenLoc(I);
4396 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4397 case RangeBefore:
4398 AdvanceToken();
4399 continue;
4400 case RangeAfter:
4401 case RangeOverlap:
4402 break;
4403 }
4404 break;
4405 }
4406
4407 // Look at all of the tokens within this range.
4408 while (MoreTokens()) {
4409 const unsigned I = NextToken();
4410 SourceLocation TokLoc = GetTokenLoc(I);
4411 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4412 case RangeBefore:
4413 assert(0 && "Infeasible");
4414 case RangeAfter:
4415 break;
4416 case RangeOverlap:
4417 Cursors[I] = cursor;
4418 AdvanceToken();
4419 continue;
4420 }
4421 break;
4422 }
4423
4424 // Save the preprocessing token index; restore the non-preprocessing
4425 // token index.
4426 PreprocessingTokIdx = TokIdx;
4427 TokIdx = SavedTokIdx;
Douglas Gregor61656112010-01-26 18:31:56 +00004428 return CXChildVisit_Recurse;
4429 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004430
Ted Kremenek680fe512010-05-05 00:55:23 +00004431 if (cursorRange.isInvalid())
4432 return CXChildVisit_Continue;
Ted Kremenek5d616142010-05-12 05:29:33 +00004433
Ted Kremenek680fe512010-05-05 00:55:23 +00004434 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4435
Ted Kremenek5d616142010-05-12 05:29:33 +00004436 // Adjust the annotated range based specific declarations.
4437 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4438 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek49be9e02010-05-18 21:09:07 +00004439 Decl *D = cxcursor::getCursorDecl(cursor);
4440 // Don't visit synthesized ObjC methods, since they have no syntatic
4441 // representation in the source.
4442 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4443 if (MD->isSynthesized())
4444 return CXChildVisit_Continue;
4445 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004446
4447 SourceLocation StartLoc;
Ted Kremenek49be9e02010-05-18 21:09:07 +00004448 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004449 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4450 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4451 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4452 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4453 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremenek5d616142010-05-12 05:29:33 +00004454 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004455
4456 if (StartLoc.isValid() && L.isValid() &&
4457 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4458 cursorRange.setBegin(StartLoc);
Ted Kremenek5d616142010-05-12 05:29:33 +00004459 }
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004460
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004461 // If the location of the cursor occurs within a macro instantiation, record
4462 // the spelling location of the cursor in our annotation map. We can then
4463 // paper over the token labelings during a post-processing step to try and
4464 // get cursor mappings for tokens that are the *arguments* of a macro
4465 // instantiation.
4466 if (L.isMacroID()) {
4467 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4468 // Only invalidate the old annotation if it isn't part of a preprocessing
4469 // directive. Here we assume that the default construction of CXCursor
4470 // results in CXCursor.kind being an initialized value (i.e., 0). If
4471 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004472
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004473 CXCursor &oldC = Annotated[rawEncoding];
4474 if (!clang_isPreprocessing(oldC.kind))
4475 oldC = cursor;
4476 }
4477
Ted Kremenek680fe512010-05-05 00:55:23 +00004478 const enum CXCursorKind K = clang_getCursorKind(parent);
4479 const CXCursor updateC =
Ted Kremenek65b2cc02010-08-25 22:16:02 +00004480 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4481 ? clang_getNullCursor() : parent;
Ted Kremenek680fe512010-05-05 00:55:23 +00004482
4483 while (MoreTokens()) {
4484 const unsigned I = NextToken();
4485 SourceLocation TokLoc = GetTokenLoc(I);
4486 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4487 case RangeBefore:
4488 Cursors[I] = updateC;
4489 AdvanceToken();
4490 continue;
4491 case RangeAfter:
Ted Kremenek680fe512010-05-05 00:55:23 +00004492 case RangeOverlap:
4493 break;
4494 }
4495 break;
4496 }
4497
4498 // Visit children to get their cursor information.
4499 const unsigned BeforeChildren = NextToken();
4500 VisitChildren(cursor);
4501 const unsigned AfterChildren = NextToken();
4502
4503 // Adjust 'Last' to the last token within the extent of the cursor.
4504 while (MoreTokens()) {
4505 const unsigned I = NextToken();
4506 SourceLocation TokLoc = GetTokenLoc(I);
4507 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4508 case RangeBefore:
4509 assert(0 && "Infeasible");
4510 case RangeAfter:
4511 break;
4512 case RangeOverlap:
4513 Cursors[I] = updateC;
4514 AdvanceToken();
4515 continue;
4516 }
4517 break;
4518 }
4519 const unsigned Last = NextToken();
Ted Kremenek63ac5992010-05-05 00:55:15 +00004520
Ted Kremenek680fe512010-05-05 00:55:23 +00004521 // Scan the tokens that are at the beginning of the cursor, but are not
4522 // capture by the child cursors.
4523
4524 // For AST elements within macros, rely on a post-annotate pass to
4525 // to correctly annotate the tokens with cursors. Otherwise we can
4526 // get confusing results of having tokens that map to cursors that really
4527 // are expanded by an instantiation.
4528 if (L.isMacroID())
4529 cursor = clang_getNullCursor();
4530
4531 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4532 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4533 break;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004534
Ted Kremenek680fe512010-05-05 00:55:23 +00004535 Cursors[I] = cursor;
4536 }
4537 // Scan the tokens that are at the end of the cursor, but are not captured
4538 // but the child cursors.
4539 for (unsigned I = AfterChildren; I != Last; ++I)
4540 Cursors[I] = cursor;
4541
4542 TokIdx = Last;
4543 return CXChildVisit_Continue;
Douglas Gregor61656112010-01-26 18:31:56 +00004544}
4545
Ted Kremenek63ac5992010-05-05 00:55:15 +00004546static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4547 CXCursor parent,
4548 CXClientData client_data) {
4549 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4550}
4551
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004552// This gets run a separate thread to avoid stack blowout.
4553static void runAnnotateTokensWorker(void *UserData) {
4554 ((AnnotateTokensWorker*)UserData)->AnnotateTokens();
4555}
4556
Ted Kremenek63ac5992010-05-05 00:55:15 +00004557extern "C" {
4558
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004559void clang_annotateTokens(CXTranslationUnit TU,
4560 CXToken *Tokens, unsigned NumTokens,
4561 CXCursor *Cursors) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004562
4563 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor61656112010-01-26 18:31:56 +00004564 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004565
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004566 // Any token we don't specifically annotate will have a NULL cursor.
4567 CXCursor C = clang_getNullCursor();
4568 for (unsigned I = 0; I != NumTokens; ++I)
4569 Cursors[I] = C;
4570
Ted Kremenek91554282010-11-16 08:15:36 +00004571 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004572 if (!CXXUnit)
Douglas Gregor61656112010-01-26 18:31:56 +00004573 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004574
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004575 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek680fe512010-05-05 00:55:23 +00004576
Douglas Gregor5272e802010-03-19 05:22:59 +00004577 // Determine the region of interest, which contains all of the tokens.
Douglas Gregor61656112010-01-26 18:31:56 +00004578 SourceRange RegionOfInterest;
Ted Kremenek680fe512010-05-05 00:55:23 +00004579 RegionOfInterest.setBegin(cxloc::translateSourceLocation(
4580 clang_getTokenLocation(TU, Tokens[0])));
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00004581 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
4582 clang_getTokenLocation(TU,
4583 Tokens[NumTokens - 1])));
Ted Kremenek680fe512010-05-05 00:55:23 +00004584
Douglas Gregor5272e802010-03-19 05:22:59 +00004585 // A mapping from the source locations found when re-lexing or traversing the
4586 // region of interest to the corresponding cursors.
4587 AnnotateTokensData Annotated;
Ted Kremenek680fe512010-05-05 00:55:23 +00004588
4589 // Relex the tokens within the source range to look for preprocessing
Douglas Gregor5272e802010-03-19 05:22:59 +00004590 // directives.
Douglas Gregor92a524f2010-03-18 00:42:48 +00004591 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4592 std::pair<FileID, unsigned> BeginLocInfo
4593 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4594 std::pair<FileID, unsigned> EndLocInfo
4595 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
Ted Kremenek680fe512010-05-05 00:55:23 +00004596
Douglas Gregor92a524f2010-03-18 00:42:48 +00004597 llvm::StringRef Buffer;
Douglas Gregor5272e802010-03-19 05:22:59 +00004598 bool Invalid = false;
4599 if (BeginLocInfo.first == EndLocInfo.first &&
4600 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4601 !Invalid) {
Douglas Gregor92a524f2010-03-18 00:42:48 +00004602 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4603 CXXUnit->getASTContext().getLangOptions(),
Ted Kremenek680fe512010-05-05 00:55:23 +00004604 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
Douglas Gregor065f8d12010-03-18 17:52:52 +00004605 Buffer.end());
Douglas Gregor92a524f2010-03-18 00:42:48 +00004606 Lex.SetCommentRetentionState(true);
Ted Kremenek680fe512010-05-05 00:55:23 +00004607
4608 // Lex tokens in raw mode until we hit the end of the range, to avoid
Douglas Gregor92a524f2010-03-18 00:42:48 +00004609 // entering #includes or expanding macros.
Douglas Gregor02ded2a2010-03-18 15:23:44 +00004610 while (true) {
Douglas Gregor92a524f2010-03-18 00:42:48 +00004611 Token Tok;
4612 Lex.LexFromRawLexer(Tok);
Ted Kremenek680fe512010-05-05 00:55:23 +00004613
Douglas Gregor92a524f2010-03-18 00:42:48 +00004614 reprocess:
4615 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4616 // We have found a preprocessing directive. Gobble it up so that we
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00004617 // don't see it while preprocessing these tokens later, but keep track
4618 // of all of the token locations inside this preprocessing directive so
4619 // that we can annotate them appropriately.
Douglas Gregor92a524f2010-03-18 00:42:48 +00004620 //
4621 // FIXME: Some simple tests here could identify macro definitions and
4622 // #undefs, to provide specific cursor kinds for those.
4623 std::vector<SourceLocation> Locations;
4624 do {
4625 Locations.push_back(Tok.getLocation());
Ted Kremenek680fe512010-05-05 00:55:23 +00004626 Lex.LexFromRawLexer(Tok);
Douglas Gregor92a524f2010-03-18 00:42:48 +00004627 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
Ted Kremenek680fe512010-05-05 00:55:23 +00004628
Douglas Gregor92a524f2010-03-18 00:42:48 +00004629 using namespace cxcursor;
4630 CXCursor Cursor
Ted Kremenek680fe512010-05-05 00:55:23 +00004631 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4632 Locations.back()),
Ted Kremenek91554282010-11-16 08:15:36 +00004633 TU);
Douglas Gregor92a524f2010-03-18 00:42:48 +00004634 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4635 Annotated[Locations[I].getRawEncoding()] = Cursor;
4636 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004637
Douglas Gregor92a524f2010-03-18 00:42:48 +00004638 if (Tok.isAtStartOfLine())
4639 goto reprocess;
Ted Kremenek680fe512010-05-05 00:55:23 +00004640
Douglas Gregor92a524f2010-03-18 00:42:48 +00004641 continue;
4642 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004643
Douglas Gregor02ded2a2010-03-18 15:23:44 +00004644 if (Tok.is(tok::eof))
Douglas Gregor92a524f2010-03-18 00:42:48 +00004645 break;
4646 }
Douglas Gregor065f8d12010-03-18 17:52:52 +00004647 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004648
Douglas Gregor5272e802010-03-19 05:22:59 +00004649 // Annotate all of the source locations in the region of interest that map to
Ted Kremenek680fe512010-05-05 00:55:23 +00004650 // a specific cursor.
4651 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
Ted Kremenek91554282010-11-16 08:15:36 +00004652 TU, RegionOfInterest);
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004653
4654 // Run the worker within a CrashRecoveryContext.
Ted Kremenekca817a3c2010-11-14 17:47:35 +00004655 // FIXME: We use a ridiculous stack size here because the data-recursion
4656 // algorithm uses a large stack frame than the non-data recursive version,
4657 // and AnnotationTokensWorker currently transforms the data-recursion
4658 // algorithm back into a traditional recursion by explicitly calling
4659 // VisitChildren(). We will need to remove this explicit recursive call.
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004660 llvm::CrashRecoveryContext CRC;
Ted Kremenekca817a3c2010-11-14 17:47:35 +00004661 if (!RunSafely(CRC, runAnnotateTokensWorker, &W,
4662 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004663 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4664 }
Douglas Gregorf2f08062011-03-08 17:10:18 +00004665
4666 // If we ran into any entities that involve context-sensitive keywords,
4667 // take another pass through the tokens to mark them as such.
4668 if (W.hasContextSensitiveKeywords()) {
4669 for (unsigned I = 0; I != NumTokens; ++I) {
4670 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4671 continue;
4672
4673 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4674 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4675 if (ObjCPropertyDecl *Property
4676 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4677 if (Property->getPropertyAttributesAsWritten() != 0 &&
4678 llvm::StringSwitch<bool>(II->getName())
4679 .Case("readonly", true)
4680 .Case("assign", true)
4681 .Case("readwrite", true)
4682 .Case("retain", true)
4683 .Case("copy", true)
4684 .Case("nonatomic", true)
4685 .Case("atomic", true)
4686 .Case("getter", true)
4687 .Case("setter", true)
4688 .Default(false))
4689 Tokens[I].int_data[0] = CXToken_Keyword;
4690 }
4691 continue;
4692 }
4693
4694 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4695 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4696 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4697 if (llvm::StringSwitch<bool>(II->getName())
4698 .Case("in", true)
4699 .Case("out", true)
4700 .Case("inout", true)
4701 .Case("oneway", true)
4702 .Case("bycopy", true)
4703 .Case("byref", true)
4704 .Default(false))
4705 Tokens[I].int_data[0] = CXToken_Keyword;
4706 continue;
4707 }
4708
4709 if (Cursors[I].kind == CXCursor_CXXMethod) {
4710 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4711 if (CXXMethodDecl *Method
4712 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4713 if ((Method->hasAttr<FinalAttr>() ||
4714 Method->hasAttr<OverrideAttr>()) &&
4715 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4716 llvm::StringSwitch<bool>(II->getName())
4717 .Case("final", true)
4718 .Case("override", true)
4719 .Default(false))
4720 Tokens[I].int_data[0] = CXToken_Keyword;
4721 }
4722 continue;
4723 }
4724
4725 if (Cursors[I].kind == CXCursor_ClassDecl ||
4726 Cursors[I].kind == CXCursor_StructDecl ||
4727 Cursors[I].kind == CXCursor_ClassTemplate) {
4728 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4729 if (II->getName() == "final") {
4730 // We have to be careful with 'final', since it could be the name
4731 // of a member class rather than the context-sensitive keyword.
4732 // So, check whether the cursor associated with this
4733 Decl *D = getCursorDecl(Cursors[I]);
4734 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4735 if ((Record->hasAttr<FinalAttr>()) &&
4736 Record->getIdentifier() != II)
4737 Tokens[I].int_data[0] = CXToken_Keyword;
4738 } else if (ClassTemplateDecl *ClassTemplate
4739 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4740 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4741 if ((Record->hasAttr<FinalAttr>()) &&
4742 Record->getIdentifier() != II)
4743 Tokens[I].int_data[0] = CXToken_Keyword;
4744 }
4745 }
4746 continue;
4747 }
4748 }
4749 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004750}
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004751} // end: extern "C"
4752
4753//===----------------------------------------------------------------------===//
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004754// Operations for querying linkage of a cursor.
4755//===----------------------------------------------------------------------===//
4756
4757extern "C" {
4758CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor5272e802010-03-19 05:22:59 +00004759 if (!clang_isDeclaration(cursor.kind))
4760 return CXLinkage_Invalid;
4761
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004762 Decl *D = cxcursor::getCursorDecl(cursor);
4763 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4764 switch (ND->getLinkage()) {
4765 case NoLinkage: return CXLinkage_NoLinkage;
4766 case InternalLinkage: return CXLinkage_Internal;
4767 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4768 case ExternalLinkage: return CXLinkage_External;
4769 };
4770
4771 return CXLinkage_Invalid;
4772}
4773} // end: extern "C"
4774
4775//===----------------------------------------------------------------------===//
Ted Kremenek4ed29252010-04-12 21:22:16 +00004776// Operations for querying language of a cursor.
4777//===----------------------------------------------------------------------===//
4778
4779static CXLanguageKind getDeclLanguage(const Decl *D) {
4780 switch (D->getKind()) {
4781 default:
4782 break;
4783 case Decl::ImplicitParam:
4784 case Decl::ObjCAtDefsField:
4785 case Decl::ObjCCategory:
4786 case Decl::ObjCCategoryImpl:
4787 case Decl::ObjCClass:
4788 case Decl::ObjCCompatibleAlias:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004789 case Decl::ObjCForwardProtocol:
4790 case Decl::ObjCImplementation:
4791 case Decl::ObjCInterface:
4792 case Decl::ObjCIvar:
4793 case Decl::ObjCMethod:
4794 case Decl::ObjCProperty:
4795 case Decl::ObjCPropertyImpl:
4796 case Decl::ObjCProtocol:
4797 return CXLanguage_ObjC;
4798 case Decl::CXXConstructor:
4799 case Decl::CXXConversion:
4800 case Decl::CXXDestructor:
4801 case Decl::CXXMethod:
4802 case Decl::CXXRecord:
4803 case Decl::ClassTemplate:
4804 case Decl::ClassTemplatePartialSpecialization:
4805 case Decl::ClassTemplateSpecialization:
4806 case Decl::Friend:
4807 case Decl::FriendTemplate:
4808 case Decl::FunctionTemplate:
4809 case Decl::LinkageSpec:
4810 case Decl::Namespace:
4811 case Decl::NamespaceAlias:
4812 case Decl::NonTypeTemplateParm:
4813 case Decl::StaticAssert:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004814 case Decl::TemplateTemplateParm:
4815 case Decl::TemplateTypeParm:
4816 case Decl::UnresolvedUsingTypename:
4817 case Decl::UnresolvedUsingValue:
4818 case Decl::Using:
4819 case Decl::UsingDirective:
4820 case Decl::UsingShadow:
4821 return CXLanguage_CPlusPlus;
4822 }
4823
4824 return CXLanguage_C;
4825}
4826
4827extern "C" {
Douglas Gregorf757a122010-08-23 23:00:57 +00004828
4829enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4830 if (clang_isDeclaration(cursor.kind))
4831 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
4832 if (D->hasAttr<UnavailableAttr>() ||
4833 (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()))
4834 return CXAvailability_Available;
4835
4836 if (D->hasAttr<DeprecatedAttr>())
4837 return CXAvailability_Deprecated;
4838 }
4839
4840 return CXAvailability_Available;
4841}
4842
Ted Kremenek4ed29252010-04-12 21:22:16 +00004843CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4844 if (clang_isDeclaration(cursor.kind))
4845 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4846
4847 return CXLanguage_Invalid;
4848}
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004849
4850 /// \brief If the given cursor is the "templated" declaration
4851 /// descibing a class or function template, return the class or
4852 /// function template.
4853static Decl *maybeGetTemplateCursor(Decl *D) {
4854 if (!D)
4855 return 0;
4856
4857 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4858 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4859 return FunTmpl;
4860
4861 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4862 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4863 return ClassTmpl;
4864
4865 return D;
4866}
4867
Douglas Gregor0576ce72010-09-22 21:22:29 +00004868CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4869 if (clang_isDeclaration(cursor.kind)) {
4870 if (Decl *D = getCursorDecl(cursor)) {
4871 DeclContext *DC = D->getDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004872 if (!DC)
4873 return clang_getNullCursor();
4874
4875 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4876 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004877 }
4878 }
4879
4880 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4881 if (Decl *D = getCursorDecl(cursor))
Ted Kremenek91554282010-11-16 08:15:36 +00004882 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004883 }
4884
4885 return clang_getNullCursor();
4886}
4887
4888CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4889 if (clang_isDeclaration(cursor.kind)) {
4890 if (Decl *D = getCursorDecl(cursor)) {
4891 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004892 if (!DC)
4893 return clang_getNullCursor();
4894
4895 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4896 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004897 }
4898 }
4899
4900 // FIXME: Note that we can't easily compute the lexical context of a
4901 // statement or expression, so we return nothing.
4902 return clang_getNullCursor();
4903}
4904
Douglas Gregor99a26af2010-10-01 20:25:15 +00004905static void CollectOverriddenMethods(DeclContext *Ctx,
4906 ObjCMethodDecl *Method,
4907 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
4908 if (!Ctx)
4909 return;
4910
4911 // If we have a class or category implementation, jump straight to the
4912 // interface.
4913 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
4914 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
4915
4916 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
4917 if (!Container)
4918 return;
4919
4920 // Check whether we have a matching method at this level.
4921 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
4922 Method->isInstanceMethod()))
4923 if (Method != Overridden) {
4924 // We found an override at this level; there is no need to look
4925 // into other protocols or categories.
4926 Methods.push_back(Overridden);
4927 return;
4928 }
4929
4930 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4931 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
4932 PEnd = Protocol->protocol_end();
4933 P != PEnd; ++P)
4934 CollectOverriddenMethods(*P, Method, Methods);
4935 }
4936
4937 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4938 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
4939 PEnd = Category->protocol_end();
4940 P != PEnd; ++P)
4941 CollectOverriddenMethods(*P, Method, Methods);
4942 }
4943
4944 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
4945 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
4946 PEnd = Interface->protocol_end();
4947 P != PEnd; ++P)
4948 CollectOverriddenMethods(*P, Method, Methods);
4949
4950 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
4951 Category; Category = Category->getNextClassCategory())
4952 CollectOverriddenMethods(Category, Method, Methods);
4953
4954 // We only look into the superclass if we haven't found anything yet.
4955 if (Methods.empty())
4956 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
4957 return CollectOverriddenMethods(Super, Method, Methods);
4958 }
4959}
4960
4961void clang_getOverriddenCursors(CXCursor cursor,
4962 CXCursor **overridden,
4963 unsigned *num_overridden) {
4964 if (overridden)
4965 *overridden = 0;
4966 if (num_overridden)
4967 *num_overridden = 0;
4968 if (!overridden || !num_overridden)
4969 return;
4970
4971 if (!clang_isDeclaration(cursor.kind))
4972 return;
4973
4974 Decl *D = getCursorDecl(cursor);
4975 if (!D)
4976 return;
4977
4978 // Handle C++ member functions.
Ted Kremenek91554282010-11-16 08:15:36 +00004979 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor99a26af2010-10-01 20:25:15 +00004980 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
4981 *num_overridden = CXXMethod->size_overridden_methods();
4982 if (!*num_overridden)
4983 return;
4984
4985 *overridden = new CXCursor [*num_overridden];
4986 unsigned I = 0;
4987 for (CXXMethodDecl::method_iterator
4988 M = CXXMethod->begin_overridden_methods(),
4989 MEnd = CXXMethod->end_overridden_methods();
4990 M != MEnd; (void)++M, ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00004991 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00004992 return;
4993 }
4994
4995 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
4996 if (!Method)
4997 return;
4998
4999 // Handle Objective-C methods.
5000 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5001 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5002
5003 if (Methods.empty())
5004 return;
5005
5006 *num_overridden = Methods.size();
5007 *overridden = new CXCursor [Methods.size()];
5008 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00005009 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005010}
5011
5012void clang_disposeOverriddenCursors(CXCursor *overridden) {
5013 delete [] overridden;
5014}
5015
Douglas Gregor796d76a2010-10-20 22:00:55 +00005016CXFile clang_getIncludedFile(CXCursor cursor) {
5017 if (cursor.kind != CXCursor_InclusionDirective)
5018 return 0;
5019
5020 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5021 return (void *)ID->getFile();
5022}
5023
Ted Kremenek4ed29252010-04-12 21:22:16 +00005024} // end: extern "C"
5025
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005026
5027//===----------------------------------------------------------------------===//
5028// C++ AST instrospection.
5029//===----------------------------------------------------------------------===//
5030
5031extern "C" {
5032unsigned clang_CXXMethod_isStatic(CXCursor C) {
5033 if (!clang_isDeclaration(C.kind))
5034 return 0;
Douglas Gregorf11309e2010-08-31 22:12:17 +00005035
5036 CXXMethodDecl *Method = 0;
5037 Decl *D = cxcursor::getCursorDecl(C);
5038 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5039 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5040 else
5041 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5042 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek0ed75492010-05-17 20:12:45 +00005043}
Ted Kremeneka10f1282010-05-18 22:32:15 +00005044
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005045} // end: extern "C"
5046
Ted Kremenek4ed29252010-04-12 21:22:16 +00005047//===----------------------------------------------------------------------===//
Ted Kremeneka5940822010-08-26 01:42:22 +00005048// Attribute introspection.
5049//===----------------------------------------------------------------------===//
5050
5051extern "C" {
5052CXType clang_getIBOutletCollectionType(CXCursor C) {
5053 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremenek91554282010-11-16 08:15:36 +00005054 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005055
5056 IBOutletCollectionAttr *A =
5057 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5058
Douglas Gregorc81a7a22011-03-06 18:55:32 +00005059 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005060}
5061} // end: extern "C"
5062
5063//===----------------------------------------------------------------------===//
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005064// Misc. utility functions.
5065//===----------------------------------------------------------------------===//
Ted Kremenekf441baf2010-02-17 00:41:40 +00005066
Daniel Dunbar087c3a32010-11-05 17:21:46 +00005067/// Default to using an 8 MB stack size on "safety" threads.
5068static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005069
5070namespace clang {
5071
5072bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenekca817a3c2010-11-14 17:47:35 +00005073 void (*Fn)(void*), void *UserData,
5074 unsigned Size) {
5075 if (!Size)
5076 Size = GetSafetyThreadStackSize();
5077 if (Size)
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005078 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5079 return CRC.RunSafely(Fn, UserData);
5080}
5081
5082unsigned GetSafetyThreadStackSize() {
5083 return SafetyStackThreadSize;
5084}
5085
5086void SetSafetyThreadStackSize(unsigned Value) {
5087 SafetyStackThreadSize = Value;
5088}
5089
5090}
5091
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005092extern "C" {
5093
Ted Kremeneka3e65702010-02-12 22:54:40 +00005094CXString clang_getClangVersion() {
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00005095 return createCXString(getClangFullVersion());
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005096}
5097
5098} // end: extern "C"