blob: 290146fa4dd1035cbabc6df716a657d4089c9ea7 [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);
Peter Collingbournee190dee2011-03-11 19:24:49 +00001752 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *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:
Abramo Bagnara6b6f0512011-03-12 09:45:03 +00002003 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
Ted Kremenek5d304a32010-11-18 00:42:18 +00002004 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}
Peter Collingbournee190dee2011-03-11 19:24:49 +00002017void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2018 UnaryExprOrTypeTraitExpr *E) {
Ted Kremenek9f49b372010-11-17 02:18:35 +00002019 EnqueueChildren(E);
2020 if (E->isArgumentType())
2021 AddTypeLoc(E->getArgumentTypeInfo());
2022}
Ted Kremenekacff73c2010-11-13 00:36:47 +00002023void EnqueueVisitor::VisitStmt(Stmt *S) {
2024 EnqueueChildren(S);
2025}
2026void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
2027 AddStmt(S->getBody());
2028 AddStmt(S->getCond());
2029 AddDecl(S->getConditionVariable());
2030}
Ted Kremenekdd0d4b42010-11-17 00:50:39 +00002031
Ted Kremenekacff73c2010-11-13 00:36:47 +00002032void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
2033 AddStmt(W->getBody());
2034 AddStmt(W->getCond());
2035 AddDecl(W->getConditionVariable());
2036}
Ted Kremenek513cd572010-11-17 00:50:50 +00002037void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
2038 AddTypeLoc(E->getQueriedTypeSourceInfo());
2039}
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002040
2041void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002042 AddTypeLoc(E->getRhsTypeSourceInfo());
Francois Pichetcf7731b2010-12-08 09:11:05 +00002043 AddTypeLoc(E->getLhsTypeSourceInfo());
Francois Pichet9dfa3ce2010-12-07 00:08:36 +00002044}
2045
Ted Kremenekacff73c2010-11-13 00:36:47 +00002046void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
2047 VisitOverloadExpr(U);
2048 if (!U->isImplicitAccess())
2049 AddStmt(U->getBase());
2050}
Ted Kremenekc1c30cd2010-11-17 00:50:43 +00002051void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
2052 AddStmt(E->getSubExpr());
2053 AddTypeLoc(E->getWrittenTypeInfo());
2054}
Douglas Gregor557f05c2011-01-19 20:34:17 +00002055void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2056 WL.push_back(SizeOfPackExprParts(E, Parent));
2057}
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002058
Ted Kremenek92209a42010-11-11 08:05:18 +00002059void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
Ted Kremenekacff73c2010-11-13 00:36:47 +00002060 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
Ted Kremenek92209a42010-11-11 08:05:18 +00002061}
2062
2063bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2064 if (RegionOfInterest.isValid()) {
2065 SourceRange Range = getRawCursorExtent(C);
2066 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2067 return false;
2068 }
2069 return true;
2070}
2071
2072bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2073 while (!WL.empty()) {
2074 // Dequeue the worklist item.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002075 VisitorJob LI = WL.back();
2076 WL.pop_back();
2077
Ted Kremenek92209a42010-11-11 08:05:18 +00002078 // Set the Parent field, then back to its old value once we're done.
2079 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2080
2081 switch (LI.getKind()) {
Ted Kremenek73227d72010-11-12 18:26:56 +00002082 case VisitorJob::DeclVisitKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002083 Decl *D = cast<DeclVisit>(&LI)->get();
Ted Kremenek73227d72010-11-12 18:26:56 +00002084 if (!D)
2085 continue;
2086
2087 // For now, perform default visitation for Decls.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002088 if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
Ted Kremenek73227d72010-11-12 18:26:56 +00002089 return true;
2090
2091 continue;
2092 }
Ted Kremenek8eaa1652010-11-17 00:50:47 +00002093 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2094 const ExplicitTemplateArgumentList *ArgList =
2095 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2096 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2097 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2098 Arg != ArgEnd; ++Arg) {
2099 if (VisitTemplateArgumentLoc(*Arg))
2100 return true;
2101 }
2102 continue;
2103 }
Ted Kremeneke12bcf52010-11-12 21:34:12 +00002104 case VisitorJob::TypeLocVisitKind: {
2105 // Perform default visitation for TypeLocs.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002106 if (Visit(cast<TypeLocVisit>(&LI)->get()))
Ted Kremeneke12bcf52010-11-12 21:34:12 +00002107 return true;
2108 continue;
2109 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00002110 case VisitorJob::LabelRefVisitKind: {
Chris Lattnerc8e630e2011-02-17 07:39:24 +00002111 LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Ted Kremenekc49211c2011-02-23 04:54:51 +00002112 if (LabelStmt *stmt = LS->getStmt()) {
2113 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2114 TU))) {
2115 return true;
2116 }
2117 }
Ted Kremeneke48db8d2010-11-17 00:50:45 +00002118 continue;
2119 }
Douglas Gregora6ce6082011-02-25 18:19:59 +00002120
Ted Kremenek83900272010-11-18 00:02:32 +00002121 case VisitorJob::NestedNameSpecifierVisitKind: {
2122 NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
2123 if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
2124 return true;
2125 continue;
2126 }
Douglas Gregora6ce6082011-02-25 18:19:59 +00002127
2128 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2129 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2130 if (VisitNestedNameSpecifierLoc(V->get()))
2131 return true;
2132 continue;
2133 }
2134
Ted Kremenek83900272010-11-18 00:02:32 +00002135 case VisitorJob::DeclarationNameInfoVisitKind: {
2136 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2137 ->get()))
2138 return true;
2139 continue;
2140 }
Ted Kremenek5d304a32010-11-18 00:42:18 +00002141 case VisitorJob::MemberRefVisitKind: {
2142 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2143 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2144 return true;
2145 continue;
2146 }
Ted Kremenek92209a42010-11-11 08:05:18 +00002147 case VisitorJob::StmtVisitKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002148 Stmt *S = cast<StmtVisit>(&LI)->get();
Ted Kremenek7716cd62010-11-11 23:11:43 +00002149 if (!S)
2150 continue;
2151
Ted Kremenek73227d72010-11-12 18:26:56 +00002152 // Update the current cursor.
Ted Kremenek92209a42010-11-11 08:05:18 +00002153 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
Ted Kremenek5d304a32010-11-18 00:42:18 +00002154 if (!IsInRegionOfInterest(Cursor))
2155 continue;
2156 switch (Visitor(Cursor, Parent, ClientData)) {
2157 case CXChildVisit_Break: return true;
2158 case CXChildVisit_Continue: break;
2159 case CXChildVisit_Recurse:
2160 EnqueueWorkList(WL, S);
Ted Kremeneke6f03042010-11-15 22:23:26 +00002161 break;
Ted Kremenek92209a42010-11-11 08:05:18 +00002162 }
Ted Kremeneke6f03042010-11-15 22:23:26 +00002163 continue;
Ted Kremenek92209a42010-11-11 08:05:18 +00002164 }
2165 case VisitorJob::MemberExprPartsKind: {
2166 // Handle the other pieces in the MemberExpr besides the base.
Ted Kremeneke6f03042010-11-15 22:23:26 +00002167 MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Ted Kremenek92209a42010-11-11 08:05:18 +00002168
2169 // Visit the nested-name-specifier
Douglas Gregorea972d32011-02-28 21:54:11 +00002170 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek92209a42010-11-11 08:05:18 +00002172 return true;
2173
2174 // Visit the declaration name.
2175 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2176 return true;
2177
2178 // Visit the explicitly-specified template arguments, if any.
2179 if (M->hasExplicitTemplateArgs()) {
2180 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2181 *ArgEnd = Arg + M->getNumTemplateArgs();
2182 Arg != ArgEnd; ++Arg) {
2183 if (VisitTemplateArgumentLoc(*Arg))
2184 return true;
2185 }
2186 }
2187 continue;
2188 }
Ted Kremenek573411b2010-11-13 00:58:18 +00002189 case VisitorJob::DeclRefExprPartsKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002190 DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Ted Kremenek573411b2010-11-13 00:58:18 +00002191 // Visit nested-name-specifier, if present.
Douglas Gregorea972d32011-02-28 21:54:11 +00002192 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2193 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenek573411b2010-11-13 00:58:18 +00002194 return true;
2195 // Visit declaration name.
2196 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2197 return true;
Ted Kremenek573411b2010-11-13 00:58:18 +00002198 continue;
2199 }
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002200 case VisitorJob::OverloadExprPartsKind: {
Ted Kremeneke6f03042010-11-15 22:23:26 +00002201 OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002202 // Visit the nested-name-specifier.
Douglas Gregor0da1d432011-02-28 20:01:57 +00002203 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2204 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002205 return true;
2206 // Visit the declaration name.
2207 if (VisitDeclarationNameInfo(O->getNameInfo()))
2208 return true;
2209 // Visit the overloaded declaration reference.
2210 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2211 return true;
Ted Kremenekcfbbeda2010-11-12 21:34:16 +00002212 continue;
2213 }
Douglas Gregor557f05c2011-01-19 20:34:17 +00002214 case VisitorJob::SizeOfPackExprPartsKind: {
2215 SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2216 NamedDecl *Pack = E->getPack();
2217 if (isa<TemplateTypeParmDecl>(Pack)) {
2218 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2219 E->getPackLoc(), TU)))
2220 return true;
2221
2222 continue;
2223 }
2224
2225 if (isa<TemplateTemplateParmDecl>(Pack)) {
2226 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2227 E->getPackLoc(), TU)))
2228 return true;
2229
2230 continue;
2231 }
2232
2233 // Non-type template parameter packs and function parameter packs are
2234 // treated like DeclRefExpr cursors.
2235 continue;
2236 }
Ted Kremenek92209a42010-11-11 08:05:18 +00002237 }
2238 }
2239 return false;
2240}
2241
Ted Kremenek5d304a32010-11-18 00:42:18 +00002242bool CursorVisitor::Visit(Stmt *S) {
Ted Kremeneka4c27ec2010-11-15 23:31:32 +00002243 VisitorWorkList *WL = 0;
2244 if (!WorkListFreeList.empty()) {
2245 WL = WorkListFreeList.back();
2246 WL->clear();
2247 WorkListFreeList.pop_back();
2248 }
2249 else {
2250 WL = new VisitorWorkList();
2251 WorkListCache.push_back(WL);
2252 }
2253 EnqueueWorkList(*WL, S);
2254 bool result = RunVisitorWorkList(*WL);
2255 WorkListFreeList.push_back(WL);
2256 return result;
Ted Kremenek92209a42010-11-11 08:05:18 +00002257}
2258
2259//===----------------------------------------------------------------------===//
2260// Misc. API hooks.
2261//===----------------------------------------------------------------------===//
2262
Douglas Gregor2c844822010-09-24 21:18:36 +00002263static llvm::sys::Mutex EnableMultithreadingMutex;
2264static bool EnabledMultithreading;
2265
Benjamin Kramer61f5d0c2009-10-18 16:11:04 +00002266extern "C" {
Douglas Gregor1e21cc72010-02-18 23:07:20 +00002267CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2268 int displayDiagnostics) {
Daniel Dunbara5af410d2010-10-08 19:30:33 +00002269 // Disable pretty stack trace functionality, which will otherwise be a very
2270 // poor citizen of the world and set up all sorts of signal handlers.
2271 llvm::DisablePrettyStackTrace = true;
2272
Daniel Dunbarc91f2ff2010-08-18 18:43:14 +00002273 // We use crash recovery to make some of our APIs more reliable, implicitly
2274 // enable it.
2275 llvm::CrashRecoveryContext::Enable();
2276
Douglas Gregor2c844822010-09-24 21:18:36 +00002277 // Enable support for multithreading in LLVM.
2278 {
2279 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2280 if (!EnabledMultithreading) {
2281 llvm::llvm_start_multithreaded();
2282 EnabledMultithreading = true;
2283 }
2284 }
2285
Douglas Gregor87752492010-01-22 20:35:53 +00002286 CIndexer *CIdxr = new CIndexer();
Steve Naroff531e2842009-10-20 14:46:24 +00002287 if (excludeDeclarationsFromPCH)
2288 CIdxr->setOnlyLocalDecls();
Douglas Gregor1e21cc72010-02-18 23:07:20 +00002289 if (displayDiagnostics)
2290 CIdxr->setDisplayDiagnostics();
Steve Naroff531e2842009-10-20 14:46:24 +00002291 return CIdxr;
Steve Naroffd5e8e862009-08-27 19:51:58 +00002292}
2293
Daniel Dunbar079203f2009-12-01 03:14:51 +00002294void clang_disposeIndex(CXIndex CIdx) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002295 if (CIdx)
2296 delete static_cast<CIndexer *>(CIdx);
Steve Naroff3aa2d732009-09-17 18:33:27 +00002297}
2298
Daniel Dunbar079203f2009-12-01 03:14:51 +00002299CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002300 const char *ast_filename) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002301 if (!CIdx)
2302 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002303
Douglas Gregor16bef852009-10-16 20:01:17 +00002304 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
Argyrios Kyrtzidis71731d62010-11-03 22:45:23 +00002305 FileSystemOptions FileSystemOpts;
2306 FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002307
Douglas Gregor7f95d262010-04-05 23:52:57 +00002308 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Ted Kremenek91554282010-11-16 08:15:36 +00002309 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002310 CXXIdx->getOnlyLocalDecls(),
2311 0, 0, true);
Ted Kremenek91554282010-11-16 08:15:36 +00002312 return MakeCXTranslationUnit(TU);
Steve Naroffd5e8e862009-08-27 19:51:58 +00002313}
2314
Douglas Gregor4a47bca2010-08-09 22:28:58 +00002315unsigned clang_defaultEditingTranslationUnitOptions() {
Douglas Gregor176d2862010-09-27 05:49:58 +00002316 return CXTranslationUnit_PrecompiledPreamble |
Douglas Gregorf5a18542010-10-27 17:24:53 +00002317 CXTranslationUnit_CacheCompletionResults |
2318 CXTranslationUnit_CXXPrecompiledPreamble;
Douglas Gregor4a47bca2010-08-09 22:28:58 +00002319}
2320
Daniel Dunbar079203f2009-12-01 03:14:51 +00002321CXTranslationUnit
2322clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2323 const char *source_filename,
2324 int num_command_line_args,
Douglas Gregor57879fa2010-09-01 16:43:19 +00002325 const char * const *command_line_args,
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002326 unsigned num_unsaved_files,
Douglas Gregor33cdd812010-02-18 18:08:43 +00002327 struct CXUnsavedFile *unsaved_files) {
Douglas Gregor99d2cf42010-07-21 18:52:53 +00002328 return clang_parseTranslationUnit(CIdx, source_filename,
2329 command_line_args, num_command_line_args,
2330 unsaved_files, num_unsaved_files,
2331 CXTranslationUnit_DetailedPreprocessingRecord);
2332}
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002333
2334struct ParseTranslationUnitInfo {
2335 CXIndex CIdx;
2336 const char *source_filename;
Douglas Gregor57879fa2010-09-01 16:43:19 +00002337 const char *const *command_line_args;
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002338 int num_command_line_args;
2339 struct CXUnsavedFile *unsaved_files;
2340 unsigned num_unsaved_files;
2341 unsigned options;
2342 CXTranslationUnit result;
2343};
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002344static void clang_parseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002345 ParseTranslationUnitInfo *PTUI =
2346 static_cast<ParseTranslationUnitInfo*>(UserData);
2347 CXIndex CIdx = PTUI->CIdx;
2348 const char *source_filename = PTUI->source_filename;
Douglas Gregor57879fa2010-09-01 16:43:19 +00002349 const char * const *command_line_args = PTUI->command_line_args;
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002350 int num_command_line_args = PTUI->num_command_line_args;
2351 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2352 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2353 unsigned options = PTUI->options;
2354 PTUI->result = 0;
Douglas Gregor99d2cf42010-07-21 18:52:53 +00002355
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002356 if (!CIdx)
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002357 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002358
Steve Naroff531e2842009-10-20 14:46:24 +00002359 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2360
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002361 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Douglas Gregor028d3e42010-08-09 20:45:32 +00002362 bool CompleteTranslationUnit
2363 = ((options & CXTranslationUnit_Incomplete) == 0);
Douglas Gregorb14904c2010-08-13 22:48:40 +00002364 bool CacheCodeCompetionResults
2365 = options & CXTranslationUnit_CacheCompletionResults;
Douglas Gregorf5a18542010-10-27 17:24:53 +00002366 bool CXXPrecompilePreamble
2367 = options & CXTranslationUnit_CXXPrecompiledPreamble;
2368 bool CXXChainedPCH
2369 = options & CXTranslationUnit_CXXChainedPCH;
Douglas Gregorb14904c2010-08-13 22:48:40 +00002370
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002371 // Configure the diagnostics.
2372 DiagnosticOptions DiagOpts;
Douglas Gregor7f95d262010-04-05 23:52:57 +00002373 llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
Douglas Gregor345c1bc2011-01-19 01:02:47 +00002374 Diags = CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
2375 command_line_args);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002376
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002377 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2378 for (unsigned I = 0; I != num_unsaved_files; ++I) {
Chris Lattner58c79342010-04-05 22:42:27 +00002379 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002380 const llvm::MemoryBuffer *Buffer
Chris Lattner58c79342010-04-05 22:42:27 +00002381 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregoraa98ed92010-01-23 00:14:00 +00002382 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2383 Buffer));
2384 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00002385
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002386 llvm::SmallVector<const char *, 16> Args;
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002387
Ted Kremenek649bf5c2009-10-22 00:03:57 +00002388 // The 'source_filename' argument is optional. If the caller does not
2389 // specify it then it is assumed that the source file is specified
2390 // in the actual argument list.
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002391 if (source_filename)
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002392 Args.push_back(source_filename);
Douglas Gregor79edde82010-07-09 18:39:07 +00002393
2394 // Since the Clang C library is primarily used by batch tools dealing with
2395 // (often very broken) source code, where spell-checking can have a
2396 // significant negative impact on performance (particularly when
2397 // precompiled headers are involved), we disable it by default.
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002398 // Only do this if we haven't found a spell-checking-related argument.
2399 bool FoundSpellCheckingArgument = false;
2400 for (int I = 0; I != num_command_line_args; ++I) {
2401 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2402 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2403 FoundSpellCheckingArgument = true;
2404 break;
Steve Naroff531e2842009-10-20 14:46:24 +00002405 }
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002406 }
2407 if (!FoundSpellCheckingArgument)
2408 Args.push_back("-fno-spell-checking");
2409
2410 Args.insert(Args.end(), command_line_args,
2411 command_line_args + num_command_line_args);
Douglas Gregorac0605e2010-01-28 06:00:51 +00002412
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002413 // Do we need the detailed preprocessing record?
2414 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002415 Args.push_back("-Xclang");
2416 Args.push_back("-detailed-preprocessing-record");
Douglas Gregorbe2d8c62010-07-23 00:33:23 +00002417 }
2418
Argyrios Kyrtzidis8d5038c2010-11-18 21:47:04 +00002419 unsigned NumErrors = Diags->getClient()->getNumErrors();
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002420 llvm::OwningPtr<ASTUnit> Unit(
2421 ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(),
2422 Diags,
2423 CXXIdx->getClangResourcesPath(),
2424 CXXIdx->getOnlyLocalDecls(),
Douglas Gregor44c6ee72010-11-11 00:39:14 +00002425 /*CaptureDiagnostics=*/true,
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002426 RemappedFiles.data(),
2427 RemappedFiles.size(),
Argyrios Kyrtzidis97d3a382011-03-08 23:35:24 +00002428 /*RemappedFilesKeepOriginalName=*/true,
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002429 PrecompilePreamble,
2430 CompleteTranslationUnit,
Douglas Gregorf5a18542010-10-27 17:24:53 +00002431 CacheCodeCompetionResults,
2432 CXXPrecompilePreamble,
2433 CXXChainedPCH));
Ted Kremenekf441baf2010-02-17 00:41:40 +00002434
Argyrios Kyrtzidis8d5038c2010-11-18 21:47:04 +00002435 if (NumErrors != Diags->getClient()->getNumErrors()) {
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002436 // Make sure to check that 'Unit' is non-NULL.
2437 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2438 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2439 DEnd = Unit->stored_diag_end();
2440 D != DEnd; ++D) {
2441 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2442 CXString Msg = clang_formatDiagnostic(&Diag,
2443 clang_defaultDiagnosticDisplayOptions());
2444 fprintf(stderr, "%s\n", clang_getCString(Msg));
2445 clang_disposeString(Msg);
2446 }
Douglas Gregord770f732010-02-22 23:17:23 +00002447#ifdef LLVM_ON_WIN32
Douglas Gregor7845f1e2010-10-11 16:52:23 +00002448 // On Windows, force a flush, since there may be multiple copies of
2449 // stderr and stdout in the file system, all with different buffers
2450 // but writing to the same device.
2451 fflush(stderr);
2452#endif
2453 }
Douglas Gregor33cdd812010-02-18 18:08:43 +00002454 }
Douglas Gregorac0605e2010-01-28 06:00:51 +00002455
Ted Kremenek91554282010-11-16 08:15:36 +00002456 PTUI->result = MakeCXTranslationUnit(Unit.take());
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002457}
2458CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2459 const char *source_filename,
Douglas Gregor57879fa2010-09-01 16:43:19 +00002460 const char * const *command_line_args,
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002461 int num_command_line_args,
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002462 struct CXUnsavedFile *unsaved_files,
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002463 unsigned num_unsaved_files,
2464 unsigned options) {
2465 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002466 num_command_line_args, unsaved_files,
2467 num_unsaved_files, options, 0 };
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002468 llvm::CrashRecoveryContext CRC;
2469
Daniel Dunbarb7383e62010-11-05 07:19:31 +00002470 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
Daniel Dunbarf10f9be2010-08-23 22:35:34 +00002471 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2472 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2473 fprintf(stderr, " 'command_line_args' : [");
2474 for (int i = 0; i != num_command_line_args; ++i) {
2475 if (i)
2476 fprintf(stderr, ", ");
2477 fprintf(stderr, "'%s'", command_line_args[i]);
2478 }
2479 fprintf(stderr, "],\n");
2480 fprintf(stderr, " 'unsaved_files' : [");
2481 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2482 if (i)
2483 fprintf(stderr, ", ");
2484 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2485 unsaved_files[i].Length);
2486 }
2487 fprintf(stderr, "],\n");
2488 fprintf(stderr, " 'options' : %d,\n", options);
2489 fprintf(stderr, "}\n");
2490
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002491 return 0;
2492 }
2493
2494 return PTUI.result;
Steve Naroff7781daa2009-10-15 20:04:39 +00002495}
2496
Douglas Gregor6bb92ec2010-08-13 15:35:05 +00002497unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2498 return CXSaveTranslationUnit_None;
2499}
2500
2501int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2502 unsigned options) {
Douglas Gregore9386682010-08-13 05:36:37 +00002503 if (!TU)
2504 return 1;
2505
Ted Kremenek91554282010-11-16 08:15:36 +00002506 return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
Douglas Gregore9386682010-08-13 05:36:37 +00002507}
Daniel Dunbar583c3b72010-08-18 18:43:17 +00002508
Daniel Dunbar079203f2009-12-01 03:14:51 +00002509void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002510 if (CTUnit) {
2511 // If the translation unit has been marked as unsafe to free, just discard
2512 // it.
Ted Kremenek91554282010-11-16 08:15:36 +00002513 if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002514 return;
2515
Ted Kremenek91554282010-11-16 08:15:36 +00002516 delete static_cast<ASTUnit *>(CTUnit->TUData);
2517 disposeCXStringPool(CTUnit->StringPool);
2518 delete CTUnit;
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002519 }
Steve Naroff3aa2d732009-09-17 18:33:27 +00002520}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00002521
Douglas Gregorde051182010-08-11 15:58:42 +00002522unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2523 return CXReparse_None;
2524}
2525
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002526struct ReparseTranslationUnitInfo {
2527 CXTranslationUnit TU;
2528 unsigned num_unsaved_files;
2529 struct CXUnsavedFile *unsaved_files;
2530 unsigned options;
2531 int result;
2532};
Douglas Gregorca5b0532010-09-23 18:47:53 +00002533
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002534static void clang_reparseTranslationUnit_Impl(void *UserData) {
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002535 ReparseTranslationUnitInfo *RTUI =
2536 static_cast<ReparseTranslationUnitInfo*>(UserData);
2537 CXTranslationUnit TU = RTUI->TU;
2538 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2539 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2540 unsigned options = RTUI->options;
2541 (void) options;
2542 RTUI->result = 1;
2543
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002544 if (!TU)
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002545 return;
Douglas Gregorca5b0532010-09-23 18:47:53 +00002546
Ted Kremenek91554282010-11-16 08:15:36 +00002547 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregorca5b0532010-09-23 18:47:53 +00002548 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002549
2550 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
2551 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2552 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2553 const llvm::MemoryBuffer *Buffer
Douglas Gregor8e984da2010-08-04 16:47:14 +00002554 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002555 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
2556 Buffer));
2557 }
2558
Douglas Gregorca5b0532010-09-23 18:47:53 +00002559 if (!CXXUnit->Reparse(RemappedFiles.data(), RemappedFiles.size()))
2560 RTUI->result = 0;
Douglas Gregoraa21cc42010-07-19 21:46:24 +00002561}
Douglas Gregorca5b0532010-09-23 18:47:53 +00002562
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002563int clang_reparseTranslationUnit(CXTranslationUnit TU,
2564 unsigned num_unsaved_files,
2565 struct CXUnsavedFile *unsaved_files,
2566 unsigned options) {
2567 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2568 options, 0 };
2569 llvm::CrashRecoveryContext CRC;
2570
Daniel Dunbarb7383e62010-11-05 07:19:31 +00002571 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
Daniel Dunbar77af1c52010-08-19 23:44:10 +00002572 fprintf(stderr, "libclang: crash detected during reparsing\n");
Ted Kremenek91554282010-11-16 08:15:36 +00002573 static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002574 return 1;
2575 }
2576
Ted Kremenek55ccf4e2010-10-29 01:06:50 +00002577
Daniel Dunbar79acdd92010-08-18 23:09:31 +00002578 return RTUI.result;
2579}
2580
Douglas Gregor028d3e42010-08-09 20:45:32 +00002581
Daniel Dunbar079203f2009-12-01 03:14:51 +00002582CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Douglas Gregor69ff5dc2010-01-29 00:47:48 +00002583 if (!CTUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002584 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00002585
Ted Kremenek91554282010-11-16 08:15:36 +00002586 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002587 return createCXString(CXXUnit->getOriginalSourceFileName(), true);
Steve Naroff38c1a7b2009-09-03 15:49:00 +00002588}
Daniel Dunbare58bd8b2009-08-28 16:30:07 +00002589
Douglas Gregord2fc7272010-01-20 00:23:15 +00002590CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00002591 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
Douglas Gregord2fc7272010-01-20 00:23:15 +00002592 return Result;
2593}
2594
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002595} // end: extern "C"
Steve Naroffd5e8e862009-08-27 19:51:58 +00002596
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002597//===----------------------------------------------------------------------===//
Douglas Gregor4f46e782010-01-19 21:36:55 +00002598// CXSourceLocation and CXSourceRange Operations.
2599//===----------------------------------------------------------------------===//
2600
Douglas Gregor816fd362010-01-22 21:44:22 +00002601extern "C" {
2602CXSourceLocation clang_getNullLocation() {
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002603 CXSourceLocation Result = { { 0, 0 }, 0 };
Douglas Gregor816fd362010-01-22 21:44:22 +00002604 return Result;
2605}
2606
2607unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
Daniel Dunbar83a23542010-01-30 23:58:27 +00002608 return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
2609 loc1.ptr_data[1] == loc2.ptr_data[1] &&
2610 loc1.int_data == loc2.int_data);
Douglas Gregor816fd362010-01-22 21:44:22 +00002611}
2612
2613CXSourceLocation clang_getLocation(CXTranslationUnit tu,
2614 CXFile file,
2615 unsigned line,
2616 unsigned column) {
Douglas Gregor0925fbc2010-04-30 19:45:53 +00002617 if (!tu || !file)
Douglas Gregor816fd362010-01-22 21:44:22 +00002618 return clang_getNullLocation();
Douglas Gregor0925fbc2010-04-30 19:45:53 +00002619
Douglas Gregore6642762011-02-03 17:17:35 +00002620 bool Logging = ::getenv("LIBCLANG_LOGGING");
Ted Kremenek91554282010-11-16 08:15:36 +00002621 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Douglas Gregore6642762011-02-03 17:17:35 +00002622 const FileEntry *File = static_cast<const FileEntry *>(file);
Douglas Gregor816fd362010-01-22 21:44:22 +00002623 SourceLocation SLoc
Douglas Gregore6642762011-02-03 17:17:35 +00002624 = CXXUnit->getSourceManager().getLocation(File, line, column);
2625 if (SLoc.isInvalid()) {
2626 if (Logging)
2627 llvm::errs() << "clang_getLocation(\"" << File->getName()
2628 << "\", " << line << ", " << column << ") = invalid\n";
2629 return clang_getNullLocation();
2630 }
2631
2632 if (Logging)
2633 llvm::errs() << "clang_getLocation(\"" << File->getName()
2634 << "\", " << line << ", " << column << ") = "
2635 << SLoc.getRawEncoding() << "\n";
David Chisnall2e16ac52010-10-15 17:07:39 +00002636
2637 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2638}
2639
2640CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
2641 CXFile file,
2642 unsigned offset) {
2643 if (!tu || !file)
2644 return clang_getNullLocation();
2645
Ted Kremenek91554282010-11-16 08:15:36 +00002646 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
David Chisnall2e16ac52010-10-15 17:07:39 +00002647 SourceLocation Start
2648 = CXXUnit->getSourceManager().getLocation(
2649 static_cast<const FileEntry *>(file),
2650 1, 1);
2651 if (Start.isInvalid()) return clang_getNullLocation();
2652
2653 SourceLocation SLoc = Start.getFileLocWithOffset(offset);
2654
2655 if (SLoc.isInvalid()) return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002656
Ted Kremenek54140272010-06-28 23:54:17 +00002657 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
Douglas Gregor816fd362010-01-22 21:44:22 +00002658}
2659
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002660CXSourceRange clang_getNullRange() {
2661 CXSourceRange Result = { { 0, 0 }, 0, 0 };
2662 return Result;
2663}
Daniel Dunbar02968e52010-02-14 10:02:57 +00002664
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002665CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
2666 if (begin.ptr_data[0] != end.ptr_data[0] ||
2667 begin.ptr_data[1] != end.ptr_data[1])
2668 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002669
2670 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002671 begin.int_data, end.int_data };
Douglas Gregor816fd362010-01-22 21:44:22 +00002672 return Result;
2673}
2674
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002675void clang_getInstantiationLocation(CXSourceLocation location,
2676 CXFile *file,
2677 unsigned *line,
2678 unsigned *column,
2679 unsigned *offset) {
Douglas Gregor4f46e782010-01-19 21:36:55 +00002680 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2681
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002682 if (!location.ptr_data[0] || Loc.isInvalid()) {
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002683 if (file)
2684 *file = 0;
2685 if (line)
2686 *line = 0;
2687 if (column)
2688 *column = 0;
2689 if (offset)
2690 *offset = 0;
2691 return;
2692 }
2693
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002694 const SourceManager &SM =
2695 *static_cast<const SourceManager*>(location.ptr_data[0]);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002696 SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
Douglas Gregor4f46e782010-01-19 21:36:55 +00002697
2698 if (file)
2699 *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));
2700 if (line)
2701 *line = SM.getInstantiationLineNumber(InstLoc);
2702 if (column)
2703 *column = SM.getInstantiationColumnNumber(InstLoc);
Douglas Gregor47751d62010-01-26 03:07:15 +00002704 if (offset)
Douglas Gregor9bd6db52010-01-26 19:19:08 +00002705 *offset = SM.getDecomposedLoc(InstLoc).second;
Douglas Gregor47751d62010-01-26 03:07:15 +00002706}
2707
Douglas Gregor229bebd2010-11-09 06:24:54 +00002708void clang_getSpellingLocation(CXSourceLocation location,
2709 CXFile *file,
2710 unsigned *line,
2711 unsigned *column,
2712 unsigned *offset) {
2713 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2714
2715 if (!location.ptr_data[0] || Loc.isInvalid()) {
2716 if (file)
2717 *file = 0;
2718 if (line)
2719 *line = 0;
2720 if (column)
2721 *column = 0;
2722 if (offset)
2723 *offset = 0;
2724 return;
2725 }
2726
2727 const SourceManager &SM =
2728 *static_cast<const SourceManager*>(location.ptr_data[0]);
2729 SourceLocation SpellLoc = Loc;
2730 if (SpellLoc.isMacroID()) {
2731 SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2732 if (SimpleSpellingLoc.isFileID() &&
2733 SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2734 SpellLoc = SimpleSpellingLoc;
2735 else
2736 SpellLoc = SM.getInstantiationLoc(SpellLoc);
2737 }
2738
2739 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2740 FileID FID = LocInfo.first;
2741 unsigned FileOffset = LocInfo.second;
2742
2743 if (file)
2744 *file = (void *)SM.getFileEntryForID(FID);
2745 if (line)
2746 *line = SM.getLineNumber(FID, FileOffset);
2747 if (column)
2748 *column = SM.getColumnNumber(FID, FileOffset);
2749 if (offset)
2750 *offset = FileOffset;
2751}
2752
Douglas Gregor4f46e782010-01-19 21:36:55 +00002753CXSourceLocation clang_getRangeStart(CXSourceRange range) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002754 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002755 range.begin_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002756 return Result;
2757}
2758
2759CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
Daniel Dunbarc4b4d392010-02-14 01:47:36 +00002760 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
Douglas Gregor4f9c3762010-01-28 00:27:43 +00002761 range.end_int_data };
Douglas Gregor4f46e782010-01-19 21:36:55 +00002762 return Result;
2763}
2764
Douglas Gregor816fd362010-01-22 21:44:22 +00002765} // end: extern "C"
2766
Douglas Gregor4f46e782010-01-19 21:36:55 +00002767//===----------------------------------------------------------------------===//
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002768// CXFile Operations.
2769//===----------------------------------------------------------------------===//
2770
2771extern "C" {
Ted Kremenekc560b682010-02-17 00:41:20 +00002772CXString clang_getFileName(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002773 if (!SFile)
Ted Kremenek91554282010-11-16 08:15:36 +00002774 return createCXString((const char*)NULL);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002775
Steve Naroff6231f182009-10-27 14:35:18 +00002776 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Ted Kremenekc560b682010-02-17 00:41:20 +00002777 return createCXString(FEnt->getName());
Steve Naroff6231f182009-10-27 14:35:18 +00002778}
2779
2780time_t clang_getFileTime(CXFile SFile) {
Douglas Gregor66a58812010-01-18 22:46:11 +00002781 if (!SFile)
2782 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002783
Steve Naroff6231f182009-10-27 14:35:18 +00002784 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2785 return FEnt->getModificationTime();
Steve Naroff26760892009-09-25 21:45:39 +00002786}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002787
Douglas Gregor816fd362010-01-22 21:44:22 +00002788CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2789 if (!tu)
2790 return 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00002791
Ted Kremenek91554282010-11-16 08:15:36 +00002792 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
Ted Kremenekf441baf2010-02-17 00:41:40 +00002793
Douglas Gregor816fd362010-01-22 21:44:22 +00002794 FileManager &FMgr = CXXUnit->getFileManager();
Chris Lattner5159f612010-11-23 08:35:12 +00002795 return const_cast<FileEntry *>(FMgr.getFile(file_name));
Douglas Gregor816fd362010-01-22 21:44:22 +00002796}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002797
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002798} // end: extern "C"
Steve Naroff26760892009-09-25 21:45:39 +00002799
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002800//===----------------------------------------------------------------------===//
2801// CXCursor Operations.
2802//===----------------------------------------------------------------------===//
2803
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002804static Decl *getDeclFromExpr(Stmt *E) {
Douglas Gregore6712982010-10-01 21:11:22 +00002805 if (CastExpr *CE = dyn_cast<CastExpr>(E))
2806 return getDeclFromExpr(CE->getSubExpr());
2807
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002808 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
2809 return RefExpr->getDecl();
Douglas Gregor263803a2010-10-22 22:24:08 +00002810 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2811 return RefExpr->getDecl();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002812 if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
2813 return ME->getMemberDecl();
2814 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
2815 return RE->getDecl();
Douglas Gregore6712982010-10-01 21:11:22 +00002816 if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
John McCallb7bd14f2010-12-02 01:19:52 +00002817 return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
Douglas Gregore6712982010-10-01 21:11:22 +00002818
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002819 if (CallExpr *CE = dyn_cast<CallExpr>(E))
2820 return getDeclFromExpr(CE->getCallee());
Douglas Gregor16443fd2010-11-05 21:11:19 +00002821 if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
2822 if (!CE->isElidable())
2823 return CE->getConstructor();
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002824 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
2825 return OME->getMethodDecl();
Ted Kremenekf441baf2010-02-17 00:41:40 +00002826
Douglas Gregore6712982010-10-01 21:11:22 +00002827 if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
2828 return PE->getProtocol();
Douglas Gregorcdbc5392011-01-15 01:15:58 +00002829 if (SubstNonTypeTemplateParmPackExpr *NTTP
2830 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
2831 return NTTP->getParameterPack();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002832 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2833 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
2834 isa<ParmVarDecl>(SizeOfPack->getPack()))
2835 return SizeOfPack->getPack();
Douglas Gregore6712982010-10-01 21:11:22 +00002836
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002837 return 0;
2838}
2839
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002840static SourceLocation getLocationFromExpr(Expr *E) {
2841 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
2842 return /*FIXME:*/Msg->getLeftLoc();
2843 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
2844 return DRE->getLocation();
Douglas Gregor263803a2010-10-22 22:24:08 +00002845 if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
2846 return RefExpr->getLocation();
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002847 if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
2848 return Member->getMemberLoc();
2849 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
2850 return Ivar->getLocation();
Douglas Gregor557f05c2011-01-19 20:34:17 +00002851 if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
2852 return SizeOfPack->getPackLoc();
2853
Daniel Dunbara4a2e5d2010-02-02 05:00:22 +00002854 return E->getLocStart();
2855}
2856
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00002857extern "C" {
Ted Kremenekf441baf2010-02-17 00:41:40 +00002858
2859unsigned clang_visitChildren(CXCursor parent,
Douglas Gregor71f3d942010-01-20 20:59:29 +00002860 CXCursorVisitor visitor,
2861 CXClientData client_data) {
Ted Kremenek91554282010-11-16 08:15:36 +00002862 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
2863 getCursorASTUnit(parent)->getMaxPCHLevel());
Douglas Gregor71f3d942010-01-20 20:59:29 +00002864 return CursorVis.VisitChildren(parent);
2865}
2866
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002867#ifndef __has_feature
2868#define __has_feature(x) 0
2869#endif
2870#if __has_feature(blocks)
2871typedef enum CXChildVisitResult
2872 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
2873
2874static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2875 CXClientData client_data) {
2876 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2877 return block(cursor, parent);
2878}
2879#else
2880// If we are compiled with a compiler that doesn't have native blocks support,
2881// define and call the block manually, so the
2882typedef struct _CXChildVisitResult
2883{
2884 void *isa;
2885 int flags;
2886 int reserved;
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002887 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
2888 CXCursor);
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002889} *CXCursorVisitorBlock;
2890
2891static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
2892 CXClientData client_data) {
2893 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
2894 return block->invoke(block, cursor, parent);
2895}
2896#endif
2897
2898
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00002899unsigned clang_visitChildrenWithBlock(CXCursor parent,
2900 CXCursorVisitorBlock block) {
David Chisnallb2aa0ef2010-11-03 14:12:26 +00002901 return clang_visitChildren(parent, visitWithBlock, block);
2902}
2903
Douglas Gregordd969c82010-01-20 21:45:58 +00002904static CXString getDeclSpelling(Decl *D) {
2905 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002906 if (!ND) {
2907 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
2908 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
2909 return createCXString(Property->getIdentifier()->getName());
2910
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002911 return createCXString("");
Douglas Gregor68dbaea2010-11-17 00:13:31 +00002912 }
2913
Douglas Gregordd969c82010-01-20 21:45:58 +00002914 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002915 return createCXString(OMD->getSelector().getAsString());
Ted Kremenekf441baf2010-02-17 00:41:40 +00002916
Douglas Gregordd969c82010-01-20 21:45:58 +00002917 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
2918 // No, this isn't the same as the code below. getIdentifier() is non-virtual
2919 // and returns different names. NamedDecl returns the class name and
2920 // ObjCCategoryImplDecl returns the category name.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002921 return createCXString(CIMP->getIdentifier()->getNameStart());
Ted Kremenekf441baf2010-02-17 00:41:40 +00002922
Douglas Gregor01a430132010-09-01 03:07:18 +00002923 if (isa<UsingDirectiveDecl>(D))
2924 return createCXString("");
2925
Ted Kremenek08de5c12010-05-19 21:51:10 +00002926 llvm::SmallString<1024> S;
2927 llvm::raw_svector_ostream os(S);
2928 ND->printName(os);
2929
2930 return createCXString(os.str());
Douglas Gregordd969c82010-01-20 21:45:58 +00002931}
Ted Kremenekf441baf2010-02-17 00:41:40 +00002932
Daniel Dunbar079203f2009-12-01 03:14:51 +00002933CXString clang_getCursorSpelling(CXCursor C) {
Douglas Gregord2fc7272010-01-20 00:23:15 +00002934 if (clang_isTranslationUnit(C.kind))
Ted Kremenek91554282010-11-16 08:15:36 +00002935 return clang_getTranslationUnitSpelling(
2936 static_cast<CXTranslationUnit>(C.data[2]));
Douglas Gregord2fc7272010-01-20 00:23:15 +00002937
Steve Naroff80a766b2009-09-02 18:26:48 +00002938 if (clang_isReference(C.kind)) {
2939 switch (C.kind) {
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00002940 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor6c8959b2010-01-16 14:00:32 +00002941 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002942 return createCXString(Super->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00002943 }
2944 case CXCursor_ObjCClassRef: {
Douglas Gregor46d66142010-01-16 17:14:40 +00002945 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002946 return createCXString(Class->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00002947 }
2948 case CXCursor_ObjCProtocolRef: {
Douglas Gregoref6eb842010-01-16 15:44:18 +00002949 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Douglas Gregor7ecd0202010-01-18 23:41:10 +00002950 assert(OID && "getCursorSpelling(): Missing protocol decl");
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002951 return createCXString(OID->getIdentifier()->getNameStart());
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00002952 }
Ted Kremenekae9e2212010-08-27 21:34:58 +00002953 case CXCursor_CXXBaseSpecifier: {
2954 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
2955 return createCXString(B->getType().getAsString());
2956 }
Douglas Gregor93f89952010-01-21 16:28:34 +00002957 case CXCursor_TypeRef: {
2958 TypeDecl *Type = getCursorTypeRef(C).first;
2959 assert(Type && "Missing type decl");
2960
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00002961 return createCXString(getCursorContext(C).getTypeDeclType(Type).
2962 getAsString());
Douglas Gregor93f89952010-01-21 16:28:34 +00002963 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00002964 case CXCursor_TemplateRef: {
2965 TemplateDecl *Template = getCursorTemplateRef(C).first;
Douglas Gregora89314e2010-08-31 23:48:11 +00002966 assert(Template && "Missing template decl");
Douglas Gregora23e8f72010-08-31 20:37:03 +00002967
2968 return createCXString(Template->getNameAsString());
2969 }
Douglas Gregora89314e2010-08-31 23:48:11 +00002970
2971 case CXCursor_NamespaceRef: {
2972 NamedDecl *NS = getCursorNamespaceRef(C).first;
2973 assert(NS && "Missing namespace decl");
2974
2975 return createCXString(NS->getNameAsString());
2976 }
Douglas Gregor93f89952010-01-21 16:28:34 +00002977
Douglas Gregorf3af3112010-09-09 21:42:20 +00002978 case CXCursor_MemberRef: {
2979 FieldDecl *Field = getCursorMemberRef(C).first;
2980 assert(Field && "Missing member decl");
2981
2982 return createCXString(Field->getNameAsString());
2983 }
2984
Douglas Gregora93ab662010-09-10 00:22:18 +00002985 case CXCursor_LabelRef: {
2986 LabelStmt *Label = getCursorLabelRef(C).first;
2987 assert(Label && "Missing label");
2988
Chris Lattnerc8e630e2011-02-17 07:39:24 +00002989 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00002990 }
2991
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00002992 case CXCursor_OverloadedDeclRef: {
2993 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
2994 if (Decl *D = Storage.dyn_cast<Decl *>()) {
2995 if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
2996 return createCXString(ND->getNameAsString());
2997 return createCXString("");
2998 }
2999 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3000 return createCXString(E->getName().getAsString());
3001 OverloadedTemplateStorage *Ovl
3002 = Storage.get<OverloadedTemplateStorage*>();
3003 if (Ovl->size() == 0)
3004 return createCXString("");
3005 return createCXString((*Ovl->begin())->getNameAsString());
3006 }
3007
Daniel Dunbar5b2f5ca2009-11-30 20:42:49 +00003008 default:
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003009 return createCXString("<not implemented>");
Steve Naroff80a766b2009-09-02 18:26:48 +00003010 }
3011 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003012
3013 if (clang_isExpression(C.kind)) {
3014 Decl *D = getDeclFromExpr(getCursorExpr(C));
3015 if (D)
Douglas Gregordd969c82010-01-20 21:45:58 +00003016 return getDeclSpelling(D);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003017 return createCXString("");
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003018 }
3019
Douglas Gregora93ab662010-09-10 00:22:18 +00003020 if (clang_isStatement(C.kind)) {
3021 Stmt *S = getCursorStmt(C);
3022 if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003023 return createCXString(Label->getName());
Douglas Gregora93ab662010-09-10 00:22:18 +00003024
3025 return createCXString("");
3026 }
3027
Douglas Gregor065f8d12010-03-18 17:52:52 +00003028 if (C.kind == CXCursor_MacroInstantiation)
3029 return createCXString(getCursorMacroInstantiation(C)->getName()
3030 ->getNameStart());
3031
Douglas Gregor06d6d322010-03-18 18:04:21 +00003032 if (C.kind == CXCursor_MacroDefinition)
3033 return createCXString(getCursorMacroDefinition(C)->getName()
3034 ->getNameStart());
3035
Douglas Gregor796d76a2010-10-20 22:00:55 +00003036 if (C.kind == CXCursor_InclusionDirective)
3037 return createCXString(getCursorInclusionDirective(C)->getFileName());
3038
Douglas Gregor5bce76c2010-01-25 16:56:17 +00003039 if (clang_isDeclaration(C.kind))
3040 return getDeclSpelling(getCursorDecl(C));
Ted Kremenek29004672010-02-17 00:41:32 +00003041
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00003042 return createCXString("");
Steve Naroff80a766b2009-09-02 18:26:48 +00003043}
3044
Douglas Gregor97c75712010-10-02 22:49:11 +00003045CXString clang_getCursorDisplayName(CXCursor C) {
3046 if (!clang_isDeclaration(C.kind))
3047 return clang_getCursorSpelling(C);
3048
3049 Decl *D = getCursorDecl(C);
3050 if (!D)
3051 return createCXString("");
3052
3053 PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3054 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3055 D = FunTmpl->getTemplatedDecl();
3056
3057 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3058 llvm::SmallString<64> Str;
3059 llvm::raw_svector_ostream OS(Str);
3060 OS << Function->getNameAsString();
3061 if (Function->getPrimaryTemplate())
3062 OS << "<>";
3063 OS << "(";
3064 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3065 if (I)
3066 OS << ", ";
3067 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3068 }
3069
3070 if (Function->isVariadic()) {
3071 if (Function->getNumParams())
3072 OS << ", ";
3073 OS << "...";
3074 }
3075 OS << ")";
3076 return createCXString(OS.str());
3077 }
3078
3079 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3080 llvm::SmallString<64> Str;
3081 llvm::raw_svector_ostream OS(Str);
3082 OS << ClassTemplate->getNameAsString();
3083 OS << "<";
3084 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3085 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3086 if (I)
3087 OS << ", ";
3088
3089 NamedDecl *Param = Params->getParam(I);
3090 if (Param->getIdentifier()) {
3091 OS << Param->getIdentifier()->getName();
3092 continue;
3093 }
3094
3095 // There is no parameter name, which makes this tricky. Try to come up
3096 // with something useful that isn't too long.
3097 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3098 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3099 else if (NonTypeTemplateParmDecl *NTTP
3100 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3101 OS << NTTP->getType().getAsString(Policy);
3102 else
3103 OS << "template<...> class";
3104 }
3105
3106 OS << ">";
3107 return createCXString(OS.str());
3108 }
3109
3110 if (ClassTemplateSpecializationDecl *ClassSpec
3111 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3112 // If the type was explicitly written, use that.
3113 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3114 return createCXString(TSInfo->getType().getAsString(Policy));
3115
3116 llvm::SmallString<64> Str;
3117 llvm::raw_svector_ostream OS(Str);
3118 OS << ClassSpec->getNameAsString();
3119 OS << TemplateSpecializationType::PrintTemplateArgumentList(
Douglas Gregor1ccc8412010-11-07 23:05:16 +00003120 ClassSpec->getTemplateArgs().data(),
3121 ClassSpec->getTemplateArgs().size(),
Douglas Gregor97c75712010-10-02 22:49:11 +00003122 Policy);
3123 return createCXString(OS.str());
3124 }
3125
3126 return clang_getCursorSpelling(C);
3127}
3128
Ted Kremenek29004672010-02-17 00:41:32 +00003129CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
Steve Naroff1054e602009-08-31 00:59:03 +00003130 switch (Kind) {
Ted Kremenek29004672010-02-17 00:41:32 +00003131 case CXCursor_FunctionDecl:
3132 return createCXString("FunctionDecl");
3133 case CXCursor_TypedefDecl:
3134 return createCXString("TypedefDecl");
3135 case CXCursor_EnumDecl:
3136 return createCXString("EnumDecl");
3137 case CXCursor_EnumConstantDecl:
3138 return createCXString("EnumConstantDecl");
3139 case CXCursor_StructDecl:
3140 return createCXString("StructDecl");
3141 case CXCursor_UnionDecl:
3142 return createCXString("UnionDecl");
3143 case CXCursor_ClassDecl:
3144 return createCXString("ClassDecl");
3145 case CXCursor_FieldDecl:
3146 return createCXString("FieldDecl");
3147 case CXCursor_VarDecl:
3148 return createCXString("VarDecl");
3149 case CXCursor_ParmDecl:
3150 return createCXString("ParmDecl");
3151 case CXCursor_ObjCInterfaceDecl:
3152 return createCXString("ObjCInterfaceDecl");
3153 case CXCursor_ObjCCategoryDecl:
3154 return createCXString("ObjCCategoryDecl");
3155 case CXCursor_ObjCProtocolDecl:
3156 return createCXString("ObjCProtocolDecl");
3157 case CXCursor_ObjCPropertyDecl:
3158 return createCXString("ObjCPropertyDecl");
3159 case CXCursor_ObjCIvarDecl:
3160 return createCXString("ObjCIvarDecl");
3161 case CXCursor_ObjCInstanceMethodDecl:
3162 return createCXString("ObjCInstanceMethodDecl");
3163 case CXCursor_ObjCClassMethodDecl:
3164 return createCXString("ObjCClassMethodDecl");
3165 case CXCursor_ObjCImplementationDecl:
3166 return createCXString("ObjCImplementationDecl");
3167 case CXCursor_ObjCCategoryImplDecl:
3168 return createCXString("ObjCCategoryImplDecl");
Ted Kremenek225b8e32010-04-13 23:39:06 +00003169 case CXCursor_CXXMethod:
3170 return createCXString("CXXMethod");
Ted Kremenek29004672010-02-17 00:41:32 +00003171 case CXCursor_UnexposedDecl:
3172 return createCXString("UnexposedDecl");
3173 case CXCursor_ObjCSuperClassRef:
3174 return createCXString("ObjCSuperClassRef");
3175 case CXCursor_ObjCProtocolRef:
3176 return createCXString("ObjCProtocolRef");
3177 case CXCursor_ObjCClassRef:
3178 return createCXString("ObjCClassRef");
3179 case CXCursor_TypeRef:
3180 return createCXString("TypeRef");
Douglas Gregora23e8f72010-08-31 20:37:03 +00003181 case CXCursor_TemplateRef:
3182 return createCXString("TemplateRef");
Douglas Gregora89314e2010-08-31 23:48:11 +00003183 case CXCursor_NamespaceRef:
3184 return createCXString("NamespaceRef");
Douglas Gregorf3af3112010-09-09 21:42:20 +00003185 case CXCursor_MemberRef:
3186 return createCXString("MemberRef");
Douglas Gregora93ab662010-09-10 00:22:18 +00003187 case CXCursor_LabelRef:
3188 return createCXString("LabelRef");
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003189 case CXCursor_OverloadedDeclRef:
3190 return createCXString("OverloadedDeclRef");
Ted Kremenek29004672010-02-17 00:41:32 +00003191 case CXCursor_UnexposedExpr:
3192 return createCXString("UnexposedExpr");
Ted Kremenek33b9a422010-04-11 21:47:37 +00003193 case CXCursor_BlockExpr:
3194 return createCXString("BlockExpr");
Ted Kremenek29004672010-02-17 00:41:32 +00003195 case CXCursor_DeclRefExpr:
3196 return createCXString("DeclRefExpr");
3197 case CXCursor_MemberRefExpr:
3198 return createCXString("MemberRefExpr");
3199 case CXCursor_CallExpr:
3200 return createCXString("CallExpr");
3201 case CXCursor_ObjCMessageExpr:
3202 return createCXString("ObjCMessageExpr");
3203 case CXCursor_UnexposedStmt:
3204 return createCXString("UnexposedStmt");
Douglas Gregora93ab662010-09-10 00:22:18 +00003205 case CXCursor_LabelStmt:
3206 return createCXString("LabelStmt");
Ted Kremenek29004672010-02-17 00:41:32 +00003207 case CXCursor_InvalidFile:
3208 return createCXString("InvalidFile");
Ted Kremenek00da3b92010-03-19 20:39:05 +00003209 case CXCursor_InvalidCode:
3210 return createCXString("InvalidCode");
Ted Kremenek29004672010-02-17 00:41:32 +00003211 case CXCursor_NoDeclFound:
3212 return createCXString("NoDeclFound");
3213 case CXCursor_NotImplemented:
3214 return createCXString("NotImplemented");
3215 case CXCursor_TranslationUnit:
3216 return createCXString("TranslationUnit");
Ted Kremenekbff31432010-02-18 03:09:07 +00003217 case CXCursor_UnexposedAttr:
3218 return createCXString("UnexposedAttr");
3219 case CXCursor_IBActionAttr:
3220 return createCXString("attribute(ibaction)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003221 case CXCursor_IBOutletAttr:
3222 return createCXString("attribute(iboutlet)");
Ted Kremenek26bde772010-05-19 17:38:06 +00003223 case CXCursor_IBOutletCollectionAttr:
3224 return createCXString("attribute(iboutletcollection)");
Douglas Gregor92a524f2010-03-18 00:42:48 +00003225 case CXCursor_PreprocessingDirective:
3226 return createCXString("preprocessing directive");
Douglas Gregor06d6d322010-03-18 18:04:21 +00003227 case CXCursor_MacroDefinition:
3228 return createCXString("macro definition");
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003229 case CXCursor_MacroInstantiation:
3230 return createCXString("macro instantiation");
Douglas Gregor796d76a2010-10-20 22:00:55 +00003231 case CXCursor_InclusionDirective:
3232 return createCXString("inclusion directive");
Ted Kremenekbd67fb22010-05-06 23:38:21 +00003233 case CXCursor_Namespace:
3234 return createCXString("Namespace");
Ted Kremenekb80cba52010-05-07 01:04:29 +00003235 case CXCursor_LinkageSpec:
3236 return createCXString("LinkageSpec");
Ted Kremenekae9e2212010-08-27 21:34:58 +00003237 case CXCursor_CXXBaseSpecifier:
3238 return createCXString("C++ base class specifier");
Douglas Gregor12bca222010-08-31 14:41:23 +00003239 case CXCursor_Constructor:
3240 return createCXString("CXXConstructor");
3241 case CXCursor_Destructor:
3242 return createCXString("CXXDestructor");
3243 case CXCursor_ConversionFunction:
3244 return createCXString("CXXConversion");
Douglas Gregor713602b2010-08-31 17:01:39 +00003245 case CXCursor_TemplateTypeParameter:
3246 return createCXString("TemplateTypeParameter");
3247 case CXCursor_NonTypeTemplateParameter:
3248 return createCXString("NonTypeTemplateParameter");
3249 case CXCursor_TemplateTemplateParameter:
3250 return createCXString("TemplateTemplateParameter");
3251 case CXCursor_FunctionTemplate:
3252 return createCXString("FunctionTemplate");
Douglas Gregor1fbaeb12010-08-31 19:02:00 +00003253 case CXCursor_ClassTemplate:
3254 return createCXString("ClassTemplate");
Douglas Gregorf96abb22010-08-31 19:31:58 +00003255 case CXCursor_ClassTemplatePartialSpecialization:
3256 return createCXString("ClassTemplatePartialSpecialization");
Douglas Gregora89314e2010-08-31 23:48:11 +00003257 case CXCursor_NamespaceAlias:
3258 return createCXString("NamespaceAlias");
Douglas Gregor01a430132010-09-01 03:07:18 +00003259 case CXCursor_UsingDirective:
3260 return createCXString("UsingDirective");
Douglas Gregora9aa29c2010-09-01 19:52:22 +00003261 case CXCursor_UsingDeclaration:
3262 return createCXString("UsingDeclaration");
Steve Naroff1054e602009-08-31 00:59:03 +00003263 }
Ted Kremenek29004672010-02-17 00:41:32 +00003264
Ted Kremenek4ba52632010-01-16 02:02:09 +00003265 llvm_unreachable("Unhandled CXCursorKind");
Ted Kremenek91554282010-11-16 08:15:36 +00003266 return createCXString((const char*) 0);
Steve Naroffd5e8e862009-08-27 19:51:58 +00003267}
Steve Naroff1054e602009-08-31 00:59:03 +00003268
Ted Kremenek29004672010-02-17 00:41:32 +00003269enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3270 CXCursor parent,
Douglas Gregor562c1f92010-01-22 19:49:59 +00003271 CXClientData client_data) {
3272 CXCursor *BestCursor = static_cast<CXCursor *>(client_data);
Douglas Gregor16443fd2010-11-05 21:11:19 +00003273
3274 // If our current best cursor is the construction of a temporary object,
3275 // don't replace that cursor with a type reference, because we want
3276 // clang_getCursor() to point at the constructor.
3277 if (clang_isExpression(BestCursor->kind) &&
3278 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3279 cursor.kind == CXCursor_TypeRef)
3280 return CXChildVisit_Recurse;
3281
Douglas Gregor3046b4d2010-12-10 07:23:11 +00003282 // Don't override a preprocessing cursor with another preprocessing
3283 // cursor; we want the outermost preprocessing cursor.
3284 if (clang_isPreprocessing(cursor.kind) &&
3285 clang_isPreprocessing(BestCursor->kind))
3286 return CXChildVisit_Recurse;
3287
Douglas Gregor562c1f92010-01-22 19:49:59 +00003288 *BestCursor = cursor;
3289 return CXChildVisit_Recurse;
3290}
Ted Kremenek29004672010-02-17 00:41:32 +00003291
Douglas Gregor816fd362010-01-22 21:44:22 +00003292CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3293 if (!TU)
Ted Kremeneke34cbde2010-01-14 01:51:23 +00003294 return clang_getNullCursor();
Ted Kremenek29004672010-02-17 00:41:32 +00003295
Ted Kremenek91554282010-11-16 08:15:36 +00003296 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00003297 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3298
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003299 // Translate the given source location to make it point at the beginning of
3300 // the token under the cursor.
Ted Kremenek97a45372010-01-25 22:34:44 +00003301 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
Ted Kremenek1e589f22010-07-29 00:52:07 +00003302
3303 // Guard against an invalid SourceLocation, or we may assert in one
3304 // of the following calls.
3305 if (SLoc.isInvalid())
3306 return clang_getNullCursor();
3307
Douglas Gregor15417cf2010-11-03 00:35:38 +00003308 bool Logging = getenv("LIBCLANG_LOGGING");
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003309 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3310 CXXUnit->getASTContext().getLangOptions());
3311
Douglas Gregor562c1f92010-01-22 19:49:59 +00003312 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
3313 if (SLoc.isValid()) {
Douglas Gregor562c1f92010-01-22 19:49:59 +00003314 // FIXME: Would be great to have a "hint" cursor, then walk from that
3315 // hint cursor upward until we find a cursor whose source range encloses
3316 // the region of interest, rather than starting from the translation unit.
Ted Kremenek91554282010-11-16 08:15:36 +00003317 CXCursor Parent = clang_getTranslationUnitCursor(TU);
3318 CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003319 Decl::MaxPCHLevel, SourceLocation(SLoc));
Douglas Gregor562c1f92010-01-22 19:49:59 +00003320 CursorVis.VisitChildren(Parent);
Steve Naroff54f22fb2009-09-15 20:25:34 +00003321 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003322
3323 if (Logging) {
3324 CXFile SearchFile;
3325 unsigned SearchLine, SearchColumn;
3326 CXFile ResultFile;
3327 unsigned ResultLine, ResultColumn;
Douglas Gregor29ee4222010-11-17 17:14:07 +00003328 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3329 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
Douglas Gregor15417cf2010-11-03 00:35:38 +00003330 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3331
3332 clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
3333 0);
3334 clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
3335 &ResultColumn, 0);
3336 SearchFileName = clang_getFileName(SearchFile);
3337 ResultFileName = clang_getFileName(ResultFile);
3338 KindSpelling = clang_getCursorKindSpelling(Result.kind);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003339 USR = clang_getCursorUSR(Result);
3340 fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
Douglas Gregor15417cf2010-11-03 00:35:38 +00003341 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3342 clang_getCString(KindSpelling),
Douglas Gregor29ee4222010-11-17 17:14:07 +00003343 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3344 clang_getCString(USR), IsDef);
Douglas Gregor15417cf2010-11-03 00:35:38 +00003345 clang_disposeString(SearchFileName);
3346 clang_disposeString(ResultFileName);
3347 clang_disposeString(KindSpelling);
Douglas Gregor29ee4222010-11-17 17:14:07 +00003348 clang_disposeString(USR);
Douglas Gregor4a5bd5f2010-12-10 01:45:00 +00003349
3350 CXCursor Definition = clang_getCursorDefinition(Result);
3351 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3352 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3353 CXString DefinitionKindSpelling
3354 = clang_getCursorKindSpelling(Definition.kind);
3355 CXFile DefinitionFile;
3356 unsigned DefinitionLine, DefinitionColumn;
3357 clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
3358 &DefinitionLine, &DefinitionColumn, 0);
3359 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
3360 fprintf(stderr, " -> %s(%s:%d:%d)\n",
3361 clang_getCString(DefinitionKindSpelling),
3362 clang_getCString(DefinitionFileName),
3363 DefinitionLine, DefinitionColumn);
3364 clang_disposeString(DefinitionFileName);
3365 clang_disposeString(DefinitionKindSpelling);
3366 }
Douglas Gregor15417cf2010-11-03 00:35:38 +00003367 }
3368
Ted Kremenek29004672010-02-17 00:41:32 +00003369 return Result;
Steve Naroffd5e8e862009-08-27 19:51:58 +00003370}
3371
Ted Kremeneke05d7802009-11-17 19:28:59 +00003372CXCursor clang_getNullCursor(void) {
Douglas Gregor58552bc2010-01-20 23:34:41 +00003373 return MakeCXCursorInvalid(CXCursor_InvalidFile);
Ted Kremeneke05d7802009-11-17 19:28:59 +00003374}
3375
3376unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00003377 return X == Y;
Ted Kremeneke05d7802009-11-17 19:28:59 +00003378}
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00003379
Douglas Gregor06a3f302010-11-20 00:09:34 +00003380unsigned clang_hashCursor(CXCursor C) {
3381 unsigned Index = 0;
3382 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3383 Index = 1;
3384
3385 return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
3386 std::make_pair(C.kind, C.data[Index]));
3387}
3388
Daniel Dunbar079203f2009-12-01 03:14:51 +00003389unsigned clang_isInvalid(enum CXCursorKind K) {
Steve Naroff54f22fb2009-09-15 20:25:34 +00003390 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3391}
3392
Daniel Dunbar079203f2009-12-01 03:14:51 +00003393unsigned clang_isDeclaration(enum CXCursorKind K) {
Steve Naroff1054e602009-08-31 00:59:03 +00003394 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
3395}
Steve Naroff772c1a42009-08-31 14:26:51 +00003396
Daniel Dunbar079203f2009-12-01 03:14:51 +00003397unsigned clang_isReference(enum CXCursorKind K) {
Steve Naroff80a766b2009-09-02 18:26:48 +00003398 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3399}
3400
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003401unsigned clang_isExpression(enum CXCursorKind K) {
3402 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3403}
3404
3405unsigned clang_isStatement(enum CXCursorKind K) {
3406 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3407}
3408
Douglas Gregord2fc7272010-01-20 00:23:15 +00003409unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3410 return K == CXCursor_TranslationUnit;
3411}
3412
Douglas Gregor92a524f2010-03-18 00:42:48 +00003413unsigned clang_isPreprocessing(enum CXCursorKind K) {
3414 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3415}
3416
Ted Kremenekff9021b2010-03-08 21:17:29 +00003417unsigned clang_isUnexposed(enum CXCursorKind K) {
3418 switch (K) {
3419 case CXCursor_UnexposedDecl:
3420 case CXCursor_UnexposedExpr:
3421 case CXCursor_UnexposedStmt:
3422 case CXCursor_UnexposedAttr:
3423 return true;
3424 default:
3425 return false;
3426 }
3427}
3428
Daniel Dunbar079203f2009-12-01 03:14:51 +00003429CXCursorKind clang_getCursorKind(CXCursor C) {
Steve Naroffef9618b2009-09-04 15:44:05 +00003430 return C.kind;
3431}
3432
Douglas Gregor66a58812010-01-18 22:46:11 +00003433CXSourceLocation clang_getCursorLocation(CXCursor C) {
3434 if (clang_isReference(C.kind)) {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003435 switch (C.kind) {
Ted Kremenekf441baf2010-02-17 00:41:40 +00003436 case CXCursor_ObjCSuperClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003437 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3438 = getCursorObjCSuperClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003439 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003440 }
3441
Ted Kremenekf441baf2010-02-17 00:41:40 +00003442 case CXCursor_ObjCProtocolRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003443 std::pair<ObjCProtocolDecl *, SourceLocation> P
3444 = getCursorObjCProtocolRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003445 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003446 }
3447
Ted Kremenekf441baf2010-02-17 00:41:40 +00003448 case CXCursor_ObjCClassRef: {
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003449 std::pair<ObjCInterfaceDecl *, SourceLocation> P
3450 = getCursorObjCClassRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003451 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003452 }
Douglas Gregor93f89952010-01-21 16:28:34 +00003453
Ted Kremenekf441baf2010-02-17 00:41:40 +00003454 case CXCursor_TypeRef: {
Douglas Gregor93f89952010-01-21 16:28:34 +00003455 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Ted Kremenek97a45372010-01-25 22:34:44 +00003456 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
Douglas Gregor93f89952010-01-21 16:28:34 +00003457 }
Douglas Gregora23e8f72010-08-31 20:37:03 +00003458
3459 case CXCursor_TemplateRef: {
3460 std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
3461 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3462 }
3463
Douglas Gregora89314e2010-08-31 23:48:11 +00003464 case CXCursor_NamespaceRef: {
3465 std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
3466 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3467 }
3468
Douglas Gregorf3af3112010-09-09 21:42:20 +00003469 case CXCursor_MemberRef: {
3470 std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3471 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3472 }
3473
Ted Kremenekae9e2212010-08-27 21:34:58 +00003474 case CXCursor_CXXBaseSpecifier: {
Douglas Gregor3478c752010-10-02 19:51:13 +00003475 CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
3476 if (!BaseSpec)
3477 return clang_getNullLocation();
3478
3479 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
3480 return cxloc::translateSourceLocation(getCursorContext(C),
3481 TSInfo->getTypeLoc().getBeginLoc());
3482
3483 return cxloc::translateSourceLocation(getCursorContext(C),
3484 BaseSpec->getSourceRange().getBegin());
Ted Kremenekae9e2212010-08-27 21:34:58 +00003485 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003486
Douglas Gregora93ab662010-09-10 00:22:18 +00003487 case CXCursor_LabelRef: {
3488 std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
3489 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
3490 }
3491
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003492 case CXCursor_OverloadedDeclRef:
3493 return cxloc::translateSourceLocation(getCursorContext(C),
3494 getCursorOverloadedDeclRef(C).second);
3495
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003496 default:
3497 // FIXME: Need a way to enumerate all non-reference cases.
3498 llvm_unreachable("Missed a reference kind");
3499 }
Douglas Gregor66a58812010-01-18 22:46:11 +00003500 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003501
3502 if (clang_isExpression(C.kind))
Ted Kremenekf441baf2010-02-17 00:41:40 +00003503 return cxloc::translateSourceLocation(getCursorContext(C),
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003504 getLocationFromExpr(getCursorExpr(C)));
3505
Douglas Gregora93ab662010-09-10 00:22:18 +00003506 if (clang_isStatement(C.kind))
3507 return cxloc::translateSourceLocation(getCursorContext(C),
3508 getCursorStmt(C)->getLocStart());
3509
Douglas Gregor92a524f2010-03-18 00:42:48 +00003510 if (C.kind == CXCursor_PreprocessingDirective) {
3511 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
3512 return cxloc::translateSourceLocation(getCursorContext(C), L);
3513 }
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003514
3515 if (C.kind == CXCursor_MacroInstantiation) {
Douglas Gregor065f8d12010-03-18 17:52:52 +00003516 SourceLocation L
3517 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin();
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003518 return cxloc::translateSourceLocation(getCursorContext(C), L);
3519 }
Douglas Gregor06d6d322010-03-18 18:04:21 +00003520
3521 if (C.kind == CXCursor_MacroDefinition) {
3522 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3523 return cxloc::translateSourceLocation(getCursorContext(C), L);
3524 }
Douglas Gregor796d76a2010-10-20 22:00:55 +00003525
3526 if (C.kind == CXCursor_InclusionDirective) {
3527 SourceLocation L
3528 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3529 return cxloc::translateSourceLocation(getCursorContext(C), L);
3530 }
3531
Ted Kremenek8278a322010-05-12 06:16:13 +00003532 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003533 return clang_getNullLocation();
Douglas Gregor66a58812010-01-18 22:46:11 +00003534
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003535 Decl *D = getCursorDecl(C);
Douglas Gregor7ecd0202010-01-18 23:41:10 +00003536 SourceLocation Loc = D->getLocation();
3537 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3538 Loc = Class->getClassLoc();
Ted Kremenek818e5c12010-11-01 23:26:51 +00003539 // FIXME: Multiple variables declared in a single declaration
3540 // currently lack the information needed to correctly determine their
3541 // ranges when accounting for the type-specifier. We use context
3542 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3543 // and if so, whether it is the first decl.
3544 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3545 if (!cxcursor::isFirstInDeclGroup(C))
3546 Loc = VD->getLocation();
3547 }
3548
Douglas Gregor7bf6b8a2010-03-22 15:53:50 +00003549 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
Douglas Gregor66a58812010-01-18 22:46:11 +00003550}
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003551
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003552} // end extern "C"
3553
3554static SourceRange getRawCursorExtent(CXCursor C) {
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003555 if (clang_isReference(C.kind)) {
3556 switch (C.kind) {
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003557 case CXCursor_ObjCSuperClassRef:
3558 return getCursorObjCSuperClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003559
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003560 case CXCursor_ObjCProtocolRef:
3561 return getCursorObjCProtocolRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003562
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003563 case CXCursor_ObjCClassRef:
3564 return getCursorObjCClassRef(C).second;
Ted Kremenekf441baf2010-02-17 00:41:40 +00003565
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003566 case CXCursor_TypeRef:
3567 return getCursorTypeRef(C).second;
Douglas Gregora23e8f72010-08-31 20:37:03 +00003568
3569 case CXCursor_TemplateRef:
3570 return getCursorTemplateRef(C).second;
3571
Douglas Gregora89314e2010-08-31 23:48:11 +00003572 case CXCursor_NamespaceRef:
3573 return getCursorNamespaceRef(C).second;
Douglas Gregorf3af3112010-09-09 21:42:20 +00003574
3575 case CXCursor_MemberRef:
3576 return getCursorMemberRef(C).second;
3577
Ted Kremenekae9e2212010-08-27 21:34:58 +00003578 case CXCursor_CXXBaseSpecifier:
Douglas Gregor3478c752010-10-02 19:51:13 +00003579 return getCursorCXXBaseSpecifier(C)->getSourceRange();
Douglas Gregor93f89952010-01-21 16:28:34 +00003580
Douglas Gregora93ab662010-09-10 00:22:18 +00003581 case CXCursor_LabelRef:
3582 return getCursorLabelRef(C).second;
3583
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003584 case CXCursor_OverloadedDeclRef:
3585 return getCursorOverloadedDeclRef(C).second;
3586
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003587 default:
3588 // FIXME: Need a way to enumerate all non-reference cases.
3589 llvm_unreachable("Missed a reference kind");
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003590 }
3591 }
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003592
3593 if (clang_isExpression(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003594 return getCursorExpr(C)->getSourceRange();
Douglas Gregor562c1f92010-01-22 19:49:59 +00003595
3596 if (clang_isStatement(C.kind))
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003597 return getCursorStmt(C)->getSourceRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003598
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003599 if (C.kind == CXCursor_PreprocessingDirective)
3600 return cxcursor::getCursorPreprocessingDirective(C);
Douglas Gregor02ded2a2010-03-18 15:23:44 +00003601
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003602 if (C.kind == CXCursor_MacroInstantiation)
3603 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange();
Douglas Gregor06d6d322010-03-18 18:04:21 +00003604
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003605 if (C.kind == CXCursor_MacroDefinition)
3606 return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
Douglas Gregor796d76a2010-10-20 22:00:55 +00003607
3608 if (C.kind == CXCursor_InclusionDirective)
3609 return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3610
Ted Kremenek818e5c12010-11-01 23:26:51 +00003611 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3612 Decl *D = cxcursor::getCursorDecl(C);
3613 SourceRange R = D->getSourceRange();
3614 // FIXME: Multiple variables declared in a single declaration
3615 // currently lack the information needed to correctly determine their
3616 // ranges when accounting for the type-specifier. We use context
3617 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3618 // and if so, whether it is the first decl.
3619 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3620 if (!cxcursor::isFirstInDeclGroup(C))
3621 R.setBegin(VD->getLocation());
3622 }
3623 return R;
3624 }
Douglas Gregor29ee4222010-11-17 17:14:07 +00003625 return SourceRange();
3626}
3627
3628/// \brief Retrieves the "raw" cursor extent, which is then extended to include
3629/// the decl-specifier-seq for declarations.
3630static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
3631 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3632 Decl *D = cxcursor::getCursorDecl(C);
3633 SourceRange R = D->getSourceRange();
Douglas Gregor29ee4222010-11-17 17:14:07 +00003634
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00003635 // Adjust the start of the location for declarations preceded by
3636 // declaration specifiers.
3637 SourceLocation StartLoc;
3638 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
3639 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
3640 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3641 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
3642 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
3643 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
3644 }
3645
3646 if (StartLoc.isValid() && R.getBegin().isValid() &&
3647 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
3648 R.setBegin(StartLoc);
3649
3650 // FIXME: Multiple variables declared in a single declaration
3651 // currently lack the information needed to correctly determine their
3652 // ranges when accounting for the type-specifier. We use context
3653 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3654 // and if so, whether it is the first decl.
3655 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3656 if (!cxcursor::isFirstInDeclGroup(C))
3657 R.setBegin(VD->getLocation());
Douglas Gregor29ee4222010-11-17 17:14:07 +00003658 }
3659
3660 return R;
3661 }
3662
3663 return getRawCursorExtent(C);
3664}
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003665
3666extern "C" {
3667
3668CXSourceRange clang_getCursorExtent(CXCursor C) {
3669 SourceRange R = getRawCursorExtent(C);
3670 if (R.isInvalid())
Douglas Gregor4f9c3762010-01-28 00:27:43 +00003671 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003672
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00003673 return cxloc::translateSourceRange(getCursorContext(C), R);
Douglas Gregor33c34ac2010-01-19 00:34:46 +00003674}
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003675
3676CXCursor clang_getCursorReferenced(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003677 if (clang_isInvalid(C.kind))
3678 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003679
Ted Kremenek91554282010-11-16 08:15:36 +00003680 CXTranslationUnit tu = getCursorTU(C);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003681 if (clang_isDeclaration(C.kind)) {
3682 Decl *D = getCursorDecl(C);
3683 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003684 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003685 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003686 return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003687 if (ObjCForwardProtocolDecl *Protocols
3688 = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00003689 return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
Douglas Gregor68dbaea2010-11-17 00:13:31 +00003690 if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
3691 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3692 return MakeCXCursor(Property, tu);
3693
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003694 return C;
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003695 }
3696
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003697 if (clang_isExpression(C.kind)) {
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003698 Expr *E = getCursorExpr(C);
3699 Decl *D = getDeclFromExpr(E);
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003700 if (D)
Ted Kremenek91554282010-11-16 08:15:36 +00003701 return MakeCXCursor(D, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003702
3703 if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Ted Kremenek91554282010-11-16 08:15:36 +00003704 return MakeCursorOverloadedDeclRef(Ovl, tu);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003705
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003706 return clang_getNullCursor();
3707 }
3708
Douglas Gregora93ab662010-09-10 00:22:18 +00003709 if (clang_isStatement(C.kind)) {
3710 Stmt *S = getCursorStmt(C);
3711 if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003712 return MakeCXCursor(Goto->getLabel()->getStmt(), getCursorDecl(C), tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003713
3714 return clang_getNullCursor();
3715 }
3716
Douglas Gregor78ae2482010-03-18 18:23:03 +00003717 if (C.kind == CXCursor_MacroInstantiation) {
3718 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003719 return MakeMacroDefinitionCursor(Def, tu);
Douglas Gregor78ae2482010-03-18 18:23:03 +00003720 }
3721
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003722 if (!clang_isReference(C.kind))
3723 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003724
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003725 switch (C.kind) {
3726 case CXCursor_ObjCSuperClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003727 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003728
3729 case CXCursor_ObjCProtocolRef: {
Ted Kremenek91554282010-11-16 08:15:36 +00003730 return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003731
3732 case CXCursor_ObjCClassRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003733 return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
Douglas Gregor93f89952010-01-21 16:28:34 +00003734
Ted Kremenekf441baf2010-02-17 00:41:40 +00003735 case CXCursor_TypeRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003736 return MakeCXCursor(getCursorTypeRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003737
3738 case CXCursor_TemplateRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003739 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
Douglas Gregora23e8f72010-08-31 20:37:03 +00003740
Douglas Gregora89314e2010-08-31 23:48:11 +00003741 case CXCursor_NamespaceRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003742 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
Douglas Gregora89314e2010-08-31 23:48:11 +00003743
Douglas Gregorf3af3112010-09-09 21:42:20 +00003744 case CXCursor_MemberRef:
Ted Kremenek91554282010-11-16 08:15:36 +00003745 return MakeCXCursor(getCursorMemberRef(C).first, tu );
Douglas Gregorf3af3112010-09-09 21:42:20 +00003746
Ted Kremenekae9e2212010-08-27 21:34:58 +00003747 case CXCursor_CXXBaseSpecifier: {
3748 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
3749 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
Ted Kremenek91554282010-11-16 08:15:36 +00003750 tu ));
Ted Kremenekae9e2212010-08-27 21:34:58 +00003751 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003752
Douglas Gregora93ab662010-09-10 00:22:18 +00003753 case CXCursor_LabelRef:
3754 // FIXME: We end up faking the "parent" declaration here because we
3755 // don't want to make CXCursor larger.
3756 return MakeCXCursor(getCursorLabelRef(C).first,
Ted Kremenek91554282010-11-16 08:15:36 +00003757 static_cast<ASTUnit*>(tu->TUData)->getASTContext()
3758 .getTranslationUnitDecl(),
3759 tu);
Douglas Gregora93ab662010-09-10 00:22:18 +00003760
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003761 case CXCursor_OverloadedDeclRef:
3762 return C;
3763
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003764 default:
3765 // We would prefer to enumerate all non-reference cursor kinds here.
3766 llvm_unreachable("Unhandled reference cursor kind");
3767 break;
3768 }
3769 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003770
Douglas Gregorad27e8b2010-01-19 01:20:04 +00003771 return clang_getNullCursor();
3772}
3773
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003774CXCursor clang_getCursorDefinition(CXCursor C) {
Douglas Gregorfed36b12010-01-20 23:57:43 +00003775 if (clang_isInvalid(C.kind))
3776 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003777
Ted Kremenek91554282010-11-16 08:15:36 +00003778 CXTranslationUnit TU = getCursorTU(C);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003779
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003780 bool WasReference = false;
Douglas Gregor8f40bbee2010-01-19 23:20:36 +00003781 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003782 C = clang_getCursorReferenced(C);
3783 WasReference = true;
3784 }
3785
Douglas Gregor78ae2482010-03-18 18:23:03 +00003786 if (C.kind == CXCursor_MacroInstantiation)
3787 return clang_getCursorReferenced(C);
3788
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003789 if (!clang_isDeclaration(C.kind))
3790 return clang_getNullCursor();
3791
3792 Decl *D = getCursorDecl(C);
3793 if (!D)
3794 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003795
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003796 switch (D->getKind()) {
3797 // Declaration kinds that don't really separate the notions of
3798 // declaration and definition.
3799 case Decl::Namespace:
3800 case Decl::Typedef:
3801 case Decl::TemplateTypeParm:
3802 case Decl::EnumConstant:
3803 case Decl::Field:
Benjamin Kramer39593702010-11-21 14:11:41 +00003804 case Decl::IndirectField:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003805 case Decl::ObjCIvar:
3806 case Decl::ObjCAtDefsField:
3807 case Decl::ImplicitParam:
3808 case Decl::ParmVar:
3809 case Decl::NonTypeTemplateParm:
3810 case Decl::TemplateTemplateParm:
3811 case Decl::ObjCCategoryImpl:
3812 case Decl::ObjCImplementation:
Abramo Bagnarad7340582010-06-05 05:09:32 +00003813 case Decl::AccessSpec:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003814 case Decl::LinkageSpec:
3815 case Decl::ObjCPropertyImpl:
3816 case Decl::FileScopeAsm:
3817 case Decl::StaticAssert:
3818 case Decl::Block:
Chris Lattnerc8e630e2011-02-17 07:39:24 +00003819 case Decl::Label: // FIXME: Is this right??
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003820 return C;
3821
3822 // Declaration kinds that don't make any sense here, but are
3823 // nonetheless harmless.
3824 case Decl::TranslationUnit:
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003825 break;
3826
3827 // Declaration kinds for which the definition is not resolvable.
3828 case Decl::UnresolvedUsingTypename:
3829 case Decl::UnresolvedUsingValue:
3830 break;
3831
3832 case Decl::UsingDirective:
Douglas Gregorfed36b12010-01-20 23:57:43 +00003833 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
Ted Kremenek91554282010-11-16 08:15:36 +00003834 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003835
3836 case Decl::NamespaceAlias:
Ted Kremenek91554282010-11-16 08:15:36 +00003837 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003838
3839 case Decl::Enum:
3840 case Decl::Record:
3841 case Decl::CXXRecord:
3842 case Decl::ClassTemplateSpecialization:
3843 case Decl::ClassTemplatePartialSpecialization:
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003844 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003845 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003846 return clang_getNullCursor();
3847
3848 case Decl::Function:
3849 case Decl::CXXMethod:
3850 case Decl::CXXConstructor:
3851 case Decl::CXXDestructor:
3852 case Decl::CXXConversion: {
3853 const FunctionDecl *Def = 0;
3854 if (cast<FunctionDecl>(D)->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003855 return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003856 return clang_getNullCursor();
3857 }
3858
3859 case Decl::Var: {
Sebastian Redl5ca79842010-02-01 20:16:42 +00003860 // Ask the variable if it has a definition.
3861 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003862 return MakeCXCursor(Def, TU);
Sebastian Redl5ca79842010-02-01 20:16:42 +00003863 return clang_getNullCursor();
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003864 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003865
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003866 case Decl::FunctionTemplate: {
3867 const FunctionDecl *Def = 0;
3868 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
Ted Kremenek91554282010-11-16 08:15:36 +00003869 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003870 return clang_getNullCursor();
3871 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00003872
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003873 case Decl::ClassTemplate: {
3874 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
Douglas Gregor0a5a2212010-02-11 01:04:33 +00003875 ->getDefinition())
Douglas Gregora23e8f72010-08-31 20:37:03 +00003876 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
Ted Kremenek91554282010-11-16 08:15:36 +00003877 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003878 return clang_getNullCursor();
3879 }
3880
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003881 case Decl::Using:
3882 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00003883 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003884
3885 case Decl::UsingShadow:
3886 return clang_getCursorDefinition(
Ted Kremenekf441baf2010-02-17 00:41:40 +00003887 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
Ted Kremenek91554282010-11-16 08:15:36 +00003888 TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003889
3890 case Decl::ObjCMethod: {
3891 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
3892 if (Method->isThisDeclarationADefinition())
3893 return C;
3894
3895 // Dig out the method definition in the associated
3896 // @implementation, if we have it.
3897 // FIXME: The ASTs should make finding the definition easier.
3898 if (ObjCInterfaceDecl *Class
3899 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
3900 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
3901 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
3902 Method->isInstanceMethod()))
3903 if (Def->isThisDeclarationADefinition())
Ted Kremenek91554282010-11-16 08:15:36 +00003904 return MakeCXCursor(Def, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003905
3906 return clang_getNullCursor();
3907 }
3908
3909 case Decl::ObjCCategory:
3910 if (ObjCCategoryImplDecl *Impl
3911 = cast<ObjCCategoryDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00003912 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003913 return clang_getNullCursor();
3914
3915 case Decl::ObjCProtocol:
3916 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
3917 return C;
3918 return clang_getNullCursor();
3919
3920 case Decl::ObjCInterface:
3921 // There are two notions of a "definition" for an Objective-C
3922 // class: the interface and its implementation. When we resolved a
3923 // reference to an Objective-C class, produce the @interface as
3924 // the definition; when we were provided with the interface,
3925 // produce the @implementation as the definition.
3926 if (WasReference) {
3927 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
3928 return C;
3929 } else if (ObjCImplementationDecl *Impl
3930 = cast<ObjCInterfaceDecl>(D)->getImplementation())
Ted Kremenek91554282010-11-16 08:15:36 +00003931 return MakeCXCursor(Impl, TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003932 return clang_getNullCursor();
Ted Kremenekf441baf2010-02-17 00:41:40 +00003933
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003934 case Decl::ObjCProperty:
3935 // FIXME: We don't really know where to find the
3936 // ObjCPropertyImplDecls that implement this property.
3937 return clang_getNullCursor();
3938
3939 case Decl::ObjCCompatibleAlias:
3940 if (ObjCInterfaceDecl *Class
3941 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
3942 if (!Class->isForwardDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00003943 return MakeCXCursor(Class, TU);
Ted Kremenekf441baf2010-02-17 00:41:40 +00003944
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003945 return clang_getNullCursor();
3946
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003947 case Decl::ObjCForwardProtocol:
3948 return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
Ted Kremenek91554282010-11-16 08:15:36 +00003949 D->getLocation(), TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003950
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003951 case Decl::ObjCClass:
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00003952 return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
Ted Kremenek91554282010-11-16 08:15:36 +00003953 TU);
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003954
3955 case Decl::Friend:
3956 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00003957 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003958 return clang_getNullCursor();
3959
3960 case Decl::FriendTemplate:
3961 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
Ted Kremenek91554282010-11-16 08:15:36 +00003962 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
Douglas Gregor6b8232f2010-01-19 19:34:47 +00003963 return clang_getNullCursor();
3964 }
3965
3966 return clang_getNullCursor();
3967}
3968
3969unsigned clang_isCursorDefinition(CXCursor C) {
3970 if (!clang_isDeclaration(C.kind))
3971 return 0;
3972
3973 return clang_getCursorDefinition(C) == C;
3974}
3975
Douglas Gregorfec4dc92010-11-19 23:44:15 +00003976CXCursor clang_getCanonicalCursor(CXCursor C) {
3977 if (!clang_isDeclaration(C.kind))
3978 return C;
3979
3980 if (Decl *D = getCursorDecl(C))
3981 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
3982
3983 return C;
3984}
3985
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003986unsigned clang_getNumOverloadedDecls(CXCursor C) {
Douglas Gregorae185302010-09-16 13:54:00 +00003987 if (C.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00003988 return 0;
3989
3990 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3991 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
3992 return E->getNumDecls();
3993
3994 if (OverloadedTemplateStorage *S
3995 = Storage.dyn_cast<OverloadedTemplateStorage*>())
3996 return S->size();
3997
3998 Decl *D = Storage.get<Decl*>();
3999 if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
Argyrios Kyrtzidis2703beb2010-11-10 05:40:41 +00004000 return Using->shadow_size();
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004001 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
4002 return Classes->size();
4003 if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
4004 return Protocols->protocol_size();
4005
4006 return 0;
4007}
4008
4009CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
Douglas Gregorae185302010-09-16 13:54:00 +00004010 if (cursor.kind != CXCursor_OverloadedDeclRef)
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004011 return clang_getNullCursor();
4012
4013 if (index >= clang_getNumOverloadedDecls(cursor))
4014 return clang_getNullCursor();
4015
Ted Kremenek91554282010-11-16 08:15:36 +00004016 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004017 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
4018 if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
Ted Kremenek91554282010-11-16 08:15:36 +00004019 return MakeCXCursor(E->decls_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004020
4021 if (OverloadedTemplateStorage *S
4022 = Storage.dyn_cast<OverloadedTemplateStorage*>())
Ted Kremenek91554282010-11-16 08:15:36 +00004023 return MakeCXCursor(S->begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004024
4025 Decl *D = Storage.get<Decl*>();
4026 if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
4027 // FIXME: This is, unfortunately, linear time.
4028 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4029 std::advance(Pos, index);
Ted Kremenek91554282010-11-16 08:15:36 +00004030 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004031 }
4032
4033 if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004034 return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004035
4036 if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
Ted Kremenek91554282010-11-16 08:15:36 +00004037 return MakeCXCursor(Protocols->protocol_begin()[index], TU);
Douglas Gregor16a2bdd2010-09-13 22:52:57 +00004038
4039 return clang_getNullCursor();
4040}
4041
Daniel Dunbarbbc569c2009-11-30 20:42:43 +00004042void clang_getDefinitionSpellingAndExtent(CXCursor C,
Steve Naroff76b8f132009-09-23 17:52:52 +00004043 const char **startBuf,
4044 const char **endBuf,
4045 unsigned *startLine,
4046 unsigned *startColumn,
4047 unsigned *endLine,
Daniel Dunbar079203f2009-12-01 03:14:51 +00004048 unsigned *endColumn) {
Douglas Gregorc58d05b2010-01-15 21:56:13 +00004049 assert(getCursorDecl(C) && "CXCursor has null decl");
4050 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
Steve Naroff76b8f132009-09-23 17:52:52 +00004051 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
4052 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004053
Steve Naroff76b8f132009-09-23 17:52:52 +00004054 SourceManager &SM = FD->getASTContext().getSourceManager();
4055 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4056 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4057 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4058 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4059 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4060 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4061}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004062
Douglas Gregor1e21cc72010-02-18 23:07:20 +00004063void clang_enableStackTraces(void) {
4064 llvm::sys::PrintStackTraceOnErrorSignal();
4065}
4066
Daniel Dunbar23420652010-11-04 01:26:29 +00004067void clang_executeOnThread(void (*fn)(void*), void *user_data,
4068 unsigned stack_size) {
4069 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4070}
4071
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004072} // end: extern "C"
Steve Naroff76b8f132009-09-23 17:52:52 +00004073
Ted Kremenekd5c6eaf2010-01-13 21:46:36 +00004074//===----------------------------------------------------------------------===//
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004075// Token-based Operations.
4076//===----------------------------------------------------------------------===//
4077
4078/* CXToken layout:
4079 * int_data[0]: a CXTokenKind
4080 * int_data[1]: starting token location
4081 * int_data[2]: token length
4082 * int_data[3]: reserved
Ted Kremenekf441baf2010-02-17 00:41:40 +00004083 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004084 * otherwise unused.
4085 */
4086extern "C" {
4087
4088CXTokenKind clang_getTokenKind(CXToken CXTok) {
4089 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4090}
4091
4092CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4093 switch (clang_getTokenKind(CXTok)) {
4094 case CXToken_Identifier:
4095 case CXToken_Keyword:
4096 // We know we have an IdentifierInfo*, so use that.
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004097 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4098 ->getNameStart());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004099
4100 case CXToken_Literal: {
4101 // We have stashed the starting pointer in the ptr_data field. Use it.
4102 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004103 return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004104 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004105
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004106 case CXToken_Punctuation:
4107 case CXToken_Comment:
4108 break;
4109 }
Ted Kremenekf441baf2010-02-17 00:41:40 +00004110
4111 // We have to find the starting buffer pointer the hard way, by
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004112 // deconstructing the source location.
Ted Kremenek91554282010-11-16 08:15:36 +00004113 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004114 if (!CXXUnit)
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00004115 return createCXString("");
Ted Kremenekf441baf2010-02-17 00:41:40 +00004116
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004117 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4118 std::pair<FileID, unsigned> LocInfo
4119 = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
Douglas Gregore0fbb832010-03-16 00:06:06 +00004120 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004121 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004122 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4123 if (Invalid)
Douglas Gregor802b7762010-03-15 22:54:52 +00004124 return createCXString("");
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004125
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004126 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004127}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004128
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004129CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004130 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004131 if (!CXXUnit)
4132 return clang_getNullLocation();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004133
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004134 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4135 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4136}
4137
4138CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Ted Kremenek91554282010-11-16 08:15:36 +00004139 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor4f9c3762010-01-28 00:27:43 +00004140 if (!CXXUnit)
4141 return clang_getNullRange();
Ted Kremenekf441baf2010-02-17 00:41:40 +00004142
4143 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004144 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4145}
Ted Kremenekf441baf2010-02-17 00:41:40 +00004146
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004147void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4148 CXToken **Tokens, unsigned *NumTokens) {
4149 if (Tokens)
4150 *Tokens = 0;
4151 if (NumTokens)
4152 *NumTokens = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004153
Ted Kremenek91554282010-11-16 08:15:36 +00004154 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004155 if (!CXXUnit || !Tokens || !NumTokens)
4156 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004157
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004158 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4159
Daniel Dunbar80daf532010-02-14 08:31:57 +00004160 SourceRange R = cxloc::translateCXSourceRange(Range);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004161 if (R.isInvalid())
4162 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004163
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004164 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4165 std::pair<FileID, unsigned> BeginLocInfo
4166 = SourceMgr.getDecomposedLoc(R.getBegin());
4167 std::pair<FileID, unsigned> EndLocInfo
4168 = SourceMgr.getDecomposedLoc(R.getEnd());
Ted Kremenekf441baf2010-02-17 00:41:40 +00004169
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004170 // Cannot tokenize across files.
4171 if (BeginLocInfo.first != EndLocInfo.first)
4172 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004173
4174 // Create a lexer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004175 bool Invalid = false;
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004176 llvm::StringRef Buffer
Douglas Gregore0fbb832010-03-16 00:06:06 +00004177 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Douglas Gregor554e0b12010-03-16 20:26:15 +00004178 if (Invalid)
4179 return;
Douglas Gregor802b7762010-03-15 22:54:52 +00004180
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004181 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4182 CXXUnit->getASTContext().getLangOptions(),
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004183 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004184 Lex.SetCommentRetentionState(true);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004185
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004186 // Lex tokens until we hit the end of the range.
Benjamin Kramereb92dc02010-03-16 14:14:31 +00004187 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004188 llvm::SmallVector<CXToken, 32> CXTokens;
4189 Token Tok;
David Chisnall1822d1f2010-10-13 21:44:48 +00004190 bool previousWasAt = false;
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004191 do {
4192 // Lex the next token
4193 Lex.LexFromRawLexer(Tok);
4194 if (Tok.is(tok::eof))
4195 break;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004196
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004197 // Initialize the CXToken.
4198 CXToken CXTok;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004199
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004200 // - Common fields
4201 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4202 CXTok.int_data[2] = Tok.getLength();
4203 CXTok.int_data[3] = 0;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004204
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004205 // - Kind-specific fields
4206 if (Tok.isLiteral()) {
4207 CXTok.int_data[0] = CXToken_Literal;
4208 CXTok.ptr_data = (void *)Tok.getLiteralData();
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004209 } else if (Tok.is(tok::raw_identifier)) {
Douglas Gregor802b7762010-03-15 22:54:52 +00004210 // Lookup the identifier to determine whether we have a keyword.
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004211 IdentifierInfo *II
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004212 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004213
David Chisnall1822d1f2010-10-13 21:44:48 +00004214 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004215 CXTok.int_data[0] = CXToken_Keyword;
4216 }
4217 else {
Abramo Bagnaraea4f7c72010-12-22 08:23:18 +00004218 CXTok.int_data[0] = Tok.is(tok::identifier)
4219 ? CXToken_Identifier
4220 : CXToken_Keyword;
Ted Kremenek15cbc3a2010-05-05 00:55:20 +00004221 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004222 CXTok.ptr_data = II;
4223 } else if (Tok.is(tok::comment)) {
4224 CXTok.int_data[0] = CXToken_Comment;
4225 CXTok.ptr_data = 0;
4226 } else {
4227 CXTok.int_data[0] = CXToken_Punctuation;
4228 CXTok.ptr_data = 0;
4229 }
4230 CXTokens.push_back(CXTok);
David Chisnall1822d1f2010-10-13 21:44:48 +00004231 previousWasAt = Tok.is(tok::at);
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004232 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
Ted Kremenekf441baf2010-02-17 00:41:40 +00004233
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004234 if (CXTokens.empty())
4235 return;
Ted Kremenekf441baf2010-02-17 00:41:40 +00004236
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004237 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4238 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4239 *NumTokens = CXTokens.size();
4240}
Douglas Gregor61656112010-01-26 18:31:56 +00004241
Ted Kremenek63ac5992010-05-05 00:55:15 +00004242void clang_disposeTokens(CXTranslationUnit TU,
4243 CXToken *Tokens, unsigned NumTokens) {
4244 free(Tokens);
4245}
4246
4247} // end: extern "C"
4248
4249//===----------------------------------------------------------------------===//
4250// Token annotation APIs.
4251//===----------------------------------------------------------------------===//
4252
Douglas Gregor61656112010-01-26 18:31:56 +00004253typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
Ted Kremenek680fe512010-05-05 00:55:23 +00004254static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4255 CXCursor parent,
4256 CXClientData client_data);
Ted Kremenek63ac5992010-05-05 00:55:15 +00004257namespace {
4258class AnnotateTokensWorker {
4259 AnnotateTokensData &Annotated;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004260 CXToken *Tokens;
4261 CXCursor *Cursors;
4262 unsigned NumTokens;
Ted Kremenek680fe512010-05-05 00:55:23 +00004263 unsigned TokIdx;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004264 unsigned PreprocessingTokIdx;
Ted Kremenek680fe512010-05-05 00:55:23 +00004265 CursorVisitor AnnotateVis;
4266 SourceManager &SrcMgr;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004267 bool HasContextSensitiveKeywords;
4268
Ted Kremenek680fe512010-05-05 00:55:23 +00004269 bool MoreTokens() const { return TokIdx < NumTokens; }
4270 unsigned NextToken() const { return TokIdx; }
4271 void AdvanceToken() { ++TokIdx; }
4272 SourceLocation GetTokenLoc(unsigned tokI) {
4273 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4274 }
4275
Ted Kremenek63ac5992010-05-05 00:55:15 +00004276public:
Ted Kremenek458c2f12010-05-05 00:55:17 +00004277 AnnotateTokensWorker(AnnotateTokensData &annotated,
Ted Kremenek680fe512010-05-05 00:55:23 +00004278 CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Ted Kremenek91554282010-11-16 08:15:36 +00004279 CXTranslationUnit tu, SourceRange RegionOfInterest)
Ted Kremenek458c2f12010-05-05 00:55:17 +00004280 : Annotated(annotated), Tokens(tokens), Cursors(cursors),
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004281 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Ted Kremenek91554282010-11-16 08:15:36 +00004282 AnnotateVis(tu,
4283 AnnotateTokensVisitor, this,
Ted Kremenek680fe512010-05-05 00:55:23 +00004284 Decl::MaxPCHLevel, RegionOfInterest),
Douglas Gregorf2f08062011-03-08 17:10:18 +00004285 SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4286 HasContextSensitiveKeywords(false) { }
Ted Kremenek458c2f12010-05-05 00:55:17 +00004287
Ted Kremenek680fe512010-05-05 00:55:23 +00004288 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004289 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ted Kremenek680fe512010-05-05 00:55:23 +00004290 void AnnotateTokens(CXCursor parent);
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004291 void AnnotateTokens() {
Ted Kremenek91554282010-11-16 08:15:36 +00004292 AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004293 }
Douglas Gregorf2f08062011-03-08 17:10:18 +00004294
4295 /// \brief Determine whether the annotator saw any cursors that have
4296 /// context-sensitive keywords.
4297 bool hasContextSensitiveKeywords() const {
4298 return HasContextSensitiveKeywords;
4299 }
Ted Kremenek63ac5992010-05-05 00:55:15 +00004300};
4301}
Douglas Gregor61656112010-01-26 18:31:56 +00004302
Ted Kremenek680fe512010-05-05 00:55:23 +00004303void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4304 // Walk the AST within the region of interest, annotating tokens
4305 // along the way.
4306 VisitChildren(parent);
Ted Kremenek458c2f12010-05-05 00:55:17 +00004307
Ted Kremenek680fe512010-05-05 00:55:23 +00004308 for (unsigned I = 0 ; I < TokIdx ; ++I) {
4309 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004310 if (Pos != Annotated.end() &&
4311 (clang_isInvalid(Cursors[I].kind) ||
4312 Pos->second.kind != CXCursor_PreprocessingDirective))
Ted Kremenek680fe512010-05-05 00:55:23 +00004313 Cursors[I] = Pos->second;
4314 }
4315
4316 // Finish up annotating any tokens left.
4317 if (!MoreTokens())
4318 return;
4319
4320 const CXCursor &C = clang_getNullCursor();
4321 for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4322 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4323 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
Ted Kremenek458c2f12010-05-05 00:55:17 +00004324 }
4325}
4326
Ted Kremenek63ac5992010-05-05 00:55:15 +00004327enum CXChildVisitResult
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004328AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004329 CXSourceLocation Loc = clang_getCursorLocation(cursor);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004330 SourceRange cursorRange = getRawCursorExtent(cursor);
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004331 if (cursorRange.isInvalid())
4332 return CXChildVisit_Recurse;
Douglas Gregorf2f08062011-03-08 17:10:18 +00004333
4334 if (!HasContextSensitiveKeywords) {
4335 // Objective-C properties can have context-sensitive keywords.
4336 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4337 if (ObjCPropertyDecl *Property
4338 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4339 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4340 }
4341 // Objective-C methods can have context-sensitive keywords.
4342 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4343 cursor.kind == CXCursor_ObjCClassMethodDecl) {
4344 if (ObjCMethodDecl *Method
4345 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4346 if (Method->getObjCDeclQualifier())
4347 HasContextSensitiveKeywords = true;
4348 else {
4349 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4350 PEnd = Method->param_end();
4351 P != PEnd; ++P) {
4352 if ((*P)->getObjCDeclQualifier()) {
4353 HasContextSensitiveKeywords = true;
4354 break;
4355 }
4356 }
4357 }
4358 }
4359 }
4360 // C++ methods can have context-sensitive keywords.
4361 else if (cursor.kind == CXCursor_CXXMethod) {
4362 if (CXXMethodDecl *Method
4363 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4364 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4365 HasContextSensitiveKeywords = true;
4366 }
4367 }
4368 // C++ classes can have context-sensitive keywords.
4369 else if (cursor.kind == CXCursor_StructDecl ||
4370 cursor.kind == CXCursor_ClassDecl ||
4371 cursor.kind == CXCursor_ClassTemplate ||
4372 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4373 if (Decl *D = getCursorDecl(cursor))
4374 if (D->hasAttr<FinalAttr>())
4375 HasContextSensitiveKeywords = true;
4376 }
4377 }
4378
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004379 if (clang_isPreprocessing(cursor.kind)) {
4380 // For macro instantiations, just note where the beginning of the macro
4381 // instantiation occurs.
4382 if (cursor.kind == CXCursor_MacroInstantiation) {
4383 Annotated[Loc.int_data] = cursor;
4384 return CXChildVisit_Recurse;
4385 }
4386
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004387 // Items in the preprocessing record are kept separate from items in
4388 // declarations, so we keep a separate token index.
4389 unsigned SavedTokIdx = TokIdx;
4390 TokIdx = PreprocessingTokIdx;
4391
4392 // Skip tokens up until we catch up to the beginning of the preprocessing
4393 // entry.
4394 while (MoreTokens()) {
4395 const unsigned I = NextToken();
4396 SourceLocation TokLoc = GetTokenLoc(I);
4397 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4398 case RangeBefore:
4399 AdvanceToken();
4400 continue;
4401 case RangeAfter:
4402 case RangeOverlap:
4403 break;
4404 }
4405 break;
4406 }
4407
4408 // Look at all of the tokens within this range.
4409 while (MoreTokens()) {
4410 const unsigned I = NextToken();
4411 SourceLocation TokLoc = GetTokenLoc(I);
4412 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4413 case RangeBefore:
4414 assert(0 && "Infeasible");
4415 case RangeAfter:
4416 break;
4417 case RangeOverlap:
4418 Cursors[I] = cursor;
4419 AdvanceToken();
4420 continue;
4421 }
4422 break;
4423 }
4424
4425 // Save the preprocessing token index; restore the non-preprocessing
4426 // token index.
4427 PreprocessingTokIdx = TokIdx;
4428 TokIdx = SavedTokIdx;
Douglas Gregor61656112010-01-26 18:31:56 +00004429 return CXChildVisit_Recurse;
4430 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004431
Ted Kremenek680fe512010-05-05 00:55:23 +00004432 if (cursorRange.isInvalid())
4433 return CXChildVisit_Continue;
Ted Kremenek5d616142010-05-12 05:29:33 +00004434
Ted Kremenek680fe512010-05-05 00:55:23 +00004435 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4436
Ted Kremenek5d616142010-05-12 05:29:33 +00004437 // Adjust the annotated range based specific declarations.
4438 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4439 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Ted Kremenek49be9e02010-05-18 21:09:07 +00004440 Decl *D = cxcursor::getCursorDecl(cursor);
4441 // Don't visit synthesized ObjC methods, since they have no syntatic
4442 // representation in the source.
4443 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
4444 if (MD->isSynthesized())
4445 return CXChildVisit_Continue;
4446 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004447
4448 SourceLocation StartLoc;
Ted Kremenek49be9e02010-05-18 21:09:07 +00004449 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004450 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4451 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4452 } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4453 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4454 StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
Ted Kremenek5d616142010-05-12 05:29:33 +00004455 }
Douglas Gregor3d0da5f2011-03-01 01:34:45 +00004456
4457 if (StartLoc.isValid() && L.isValid() &&
4458 SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
4459 cursorRange.setBegin(StartLoc);
Ted Kremenek5d616142010-05-12 05:29:33 +00004460 }
Douglas Gregor9aaf7f62010-11-01 20:13:04 +00004461
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004462 // If the location of the cursor occurs within a macro instantiation, record
4463 // the spelling location of the cursor in our annotation map. We can then
4464 // paper over the token labelings during a post-processing step to try and
4465 // get cursor mappings for tokens that are the *arguments* of a macro
4466 // instantiation.
4467 if (L.isMacroID()) {
4468 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
4469 // Only invalidate the old annotation if it isn't part of a preprocessing
4470 // directive. Here we assume that the default construction of CXCursor
4471 // results in CXCursor.kind being an initialized value (i.e., 0). If
4472 // this isn't the case, we can fix by doing lookup + insertion.
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004473
Ted Kremenekf4ade0a2010-08-14 01:14:06 +00004474 CXCursor &oldC = Annotated[rawEncoding];
4475 if (!clang_isPreprocessing(oldC.kind))
4476 oldC = cursor;
4477 }
4478
Ted Kremenek680fe512010-05-05 00:55:23 +00004479 const enum CXCursorKind K = clang_getCursorKind(parent);
4480 const CXCursor updateC =
Ted Kremenek65b2cc02010-08-25 22:16:02 +00004481 (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4482 ? clang_getNullCursor() : parent;
Ted Kremenek680fe512010-05-05 00:55:23 +00004483
4484 while (MoreTokens()) {
4485 const unsigned I = NextToken();
4486 SourceLocation TokLoc = GetTokenLoc(I);
4487 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4488 case RangeBefore:
4489 Cursors[I] = updateC;
4490 AdvanceToken();
4491 continue;
4492 case RangeAfter:
Ted Kremenek680fe512010-05-05 00:55:23 +00004493 case RangeOverlap:
4494 break;
4495 }
4496 break;
4497 }
4498
4499 // Visit children to get their cursor information.
4500 const unsigned BeforeChildren = NextToken();
4501 VisitChildren(cursor);
4502 const unsigned AfterChildren = NextToken();
4503
4504 // Adjust 'Last' to the last token within the extent of the cursor.
4505 while (MoreTokens()) {
4506 const unsigned I = NextToken();
4507 SourceLocation TokLoc = GetTokenLoc(I);
4508 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
4509 case RangeBefore:
4510 assert(0 && "Infeasible");
4511 case RangeAfter:
4512 break;
4513 case RangeOverlap:
4514 Cursors[I] = updateC;
4515 AdvanceToken();
4516 continue;
4517 }
4518 break;
4519 }
4520 const unsigned Last = NextToken();
Ted Kremenek63ac5992010-05-05 00:55:15 +00004521
Ted Kremenek680fe512010-05-05 00:55:23 +00004522 // Scan the tokens that are at the beginning of the cursor, but are not
4523 // capture by the child cursors.
4524
4525 // For AST elements within macros, rely on a post-annotate pass to
4526 // to correctly annotate the tokens with cursors. Otherwise we can
4527 // get confusing results of having tokens that map to cursors that really
4528 // are expanded by an instantiation.
4529 if (L.isMacroID())
4530 cursor = clang_getNullCursor();
4531
4532 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4533 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4534 break;
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004535
Ted Kremenek680fe512010-05-05 00:55:23 +00004536 Cursors[I] = cursor;
4537 }
4538 // Scan the tokens that are at the end of the cursor, but are not captured
4539 // but the child cursors.
4540 for (unsigned I = AfterChildren; I != Last; ++I)
4541 Cursors[I] = cursor;
4542
4543 TokIdx = Last;
4544 return CXChildVisit_Continue;
Douglas Gregor61656112010-01-26 18:31:56 +00004545}
4546
Ted Kremenek63ac5992010-05-05 00:55:15 +00004547static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4548 CXCursor parent,
4549 CXClientData client_data) {
4550 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
4551}
4552
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004553// This gets run a separate thread to avoid stack blowout.
4554static void runAnnotateTokensWorker(void *UserData) {
4555 ((AnnotateTokensWorker*)UserData)->AnnotateTokens();
4556}
4557
Ted Kremenek63ac5992010-05-05 00:55:15 +00004558extern "C" {
4559
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004560void clang_annotateTokens(CXTranslationUnit TU,
4561 CXToken *Tokens, unsigned NumTokens,
4562 CXCursor *Cursors) {
Ted Kremenek680fe512010-05-05 00:55:23 +00004563
4564 if (NumTokens == 0 || !Tokens || !Cursors)
Douglas Gregor61656112010-01-26 18:31:56 +00004565 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004566
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004567 // Any token we don't specifically annotate will have a NULL cursor.
4568 CXCursor C = clang_getNullCursor();
4569 for (unsigned I = 0; I != NumTokens; ++I)
4570 Cursors[I] = C;
4571
Ted Kremenek91554282010-11-16 08:15:36 +00004572 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
Douglas Gregoradfdccf2010-10-21 06:10:04 +00004573 if (!CXXUnit)
Douglas Gregor61656112010-01-26 18:31:56 +00004574 return;
Ted Kremenek680fe512010-05-05 00:55:23 +00004575
Douglas Gregor0c7c2f82010-03-05 21:16:25 +00004576 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ted Kremenek680fe512010-05-05 00:55:23 +00004577
Douglas Gregor5272e802010-03-19 05:22:59 +00004578 // Determine the region of interest, which contains all of the tokens.
Douglas Gregor61656112010-01-26 18:31:56 +00004579 SourceRange RegionOfInterest;
Ted Kremenek680fe512010-05-05 00:55:23 +00004580 RegionOfInterest.setBegin(cxloc::translateSourceLocation(
4581 clang_getTokenLocation(TU, Tokens[0])));
Douglas Gregorcd8bdd02010-07-22 20:22:31 +00004582 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
4583 clang_getTokenLocation(TU,
4584 Tokens[NumTokens - 1])));
Ted Kremenek680fe512010-05-05 00:55:23 +00004585
Douglas Gregor5272e802010-03-19 05:22:59 +00004586 // A mapping from the source locations found when re-lexing or traversing the
4587 // region of interest to the corresponding cursors.
4588 AnnotateTokensData Annotated;
Ted Kremenek680fe512010-05-05 00:55:23 +00004589
4590 // Relex the tokens within the source range to look for preprocessing
Douglas Gregor5272e802010-03-19 05:22:59 +00004591 // directives.
Douglas Gregor92a524f2010-03-18 00:42:48 +00004592 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4593 std::pair<FileID, unsigned> BeginLocInfo
4594 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
4595 std::pair<FileID, unsigned> EndLocInfo
4596 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
Ted Kremenek680fe512010-05-05 00:55:23 +00004597
Douglas Gregor92a524f2010-03-18 00:42:48 +00004598 llvm::StringRef Buffer;
Douglas Gregor5272e802010-03-19 05:22:59 +00004599 bool Invalid = false;
4600 if (BeginLocInfo.first == EndLocInfo.first &&
4601 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
4602 !Invalid) {
Douglas Gregor92a524f2010-03-18 00:42:48 +00004603 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4604 CXXUnit->getASTContext().getLangOptions(),
Ted Kremenek680fe512010-05-05 00:55:23 +00004605 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
Douglas Gregor065f8d12010-03-18 17:52:52 +00004606 Buffer.end());
Douglas Gregor92a524f2010-03-18 00:42:48 +00004607 Lex.SetCommentRetentionState(true);
Ted Kremenek680fe512010-05-05 00:55:23 +00004608
4609 // Lex tokens in raw mode until we hit the end of the range, to avoid
Douglas Gregor92a524f2010-03-18 00:42:48 +00004610 // entering #includes or expanding macros.
Douglas Gregor02ded2a2010-03-18 15:23:44 +00004611 while (true) {
Douglas Gregor92a524f2010-03-18 00:42:48 +00004612 Token Tok;
4613 Lex.LexFromRawLexer(Tok);
Ted Kremenek680fe512010-05-05 00:55:23 +00004614
Douglas Gregor92a524f2010-03-18 00:42:48 +00004615 reprocess:
4616 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
4617 // We have found a preprocessing directive. Gobble it up so that we
Daniel Dunbar9aff85e2010-11-05 07:19:21 +00004618 // don't see it while preprocessing these tokens later, but keep track
4619 // of all of the token locations inside this preprocessing directive so
4620 // that we can annotate them appropriately.
Douglas Gregor92a524f2010-03-18 00:42:48 +00004621 //
4622 // FIXME: Some simple tests here could identify macro definitions and
4623 // #undefs, to provide specific cursor kinds for those.
4624 std::vector<SourceLocation> Locations;
4625 do {
4626 Locations.push_back(Tok.getLocation());
Ted Kremenek680fe512010-05-05 00:55:23 +00004627 Lex.LexFromRawLexer(Tok);
Douglas Gregor92a524f2010-03-18 00:42:48 +00004628 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
Ted Kremenek680fe512010-05-05 00:55:23 +00004629
Douglas Gregor92a524f2010-03-18 00:42:48 +00004630 using namespace cxcursor;
4631 CXCursor Cursor
Ted Kremenek680fe512010-05-05 00:55:23 +00004632 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
4633 Locations.back()),
Ted Kremenek91554282010-11-16 08:15:36 +00004634 TU);
Douglas Gregor92a524f2010-03-18 00:42:48 +00004635 for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
4636 Annotated[Locations[I].getRawEncoding()] = Cursor;
4637 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004638
Douglas Gregor92a524f2010-03-18 00:42:48 +00004639 if (Tok.isAtStartOfLine())
4640 goto reprocess;
Ted Kremenek680fe512010-05-05 00:55:23 +00004641
Douglas Gregor92a524f2010-03-18 00:42:48 +00004642 continue;
4643 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004644
Douglas Gregor02ded2a2010-03-18 15:23:44 +00004645 if (Tok.is(tok::eof))
Douglas Gregor92a524f2010-03-18 00:42:48 +00004646 break;
4647 }
Douglas Gregor065f8d12010-03-18 17:52:52 +00004648 }
Ted Kremenek680fe512010-05-05 00:55:23 +00004649
Douglas Gregor5272e802010-03-19 05:22:59 +00004650 // Annotate all of the source locations in the region of interest that map to
Ted Kremenek680fe512010-05-05 00:55:23 +00004651 // a specific cursor.
4652 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
Ted Kremenek91554282010-11-16 08:15:36 +00004653 TU, RegionOfInterest);
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004654
4655 // Run the worker within a CrashRecoveryContext.
Ted Kremenekca817a3c2010-11-14 17:47:35 +00004656 // FIXME: We use a ridiculous stack size here because the data-recursion
4657 // algorithm uses a large stack frame than the non-data recursive version,
4658 // and AnnotationTokensWorker currently transforms the data-recursion
4659 // algorithm back into a traditional recursion by explicitly calling
4660 // VisitChildren(). We will need to remove this explicit recursive call.
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004661 llvm::CrashRecoveryContext CRC;
Ted Kremenekca817a3c2010-11-14 17:47:35 +00004662 if (!RunSafely(CRC, runAnnotateTokensWorker, &W,
4663 GetSafetyThreadStackSize() * 2)) {
Ted Kremenekc7a5bae2010-11-11 08:05:23 +00004664 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
4665 }
Douglas Gregorf2f08062011-03-08 17:10:18 +00004666
4667 // If we ran into any entities that involve context-sensitive keywords,
4668 // take another pass through the tokens to mark them as such.
4669 if (W.hasContextSensitiveKeywords()) {
4670 for (unsigned I = 0; I != NumTokens; ++I) {
4671 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
4672 continue;
4673
4674 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
4675 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4676 if (ObjCPropertyDecl *Property
4677 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
4678 if (Property->getPropertyAttributesAsWritten() != 0 &&
4679 llvm::StringSwitch<bool>(II->getName())
4680 .Case("readonly", true)
4681 .Case("assign", true)
4682 .Case("readwrite", true)
4683 .Case("retain", true)
4684 .Case("copy", true)
4685 .Case("nonatomic", true)
4686 .Case("atomic", true)
4687 .Case("getter", true)
4688 .Case("setter", true)
4689 .Default(false))
4690 Tokens[I].int_data[0] = CXToken_Keyword;
4691 }
4692 continue;
4693 }
4694
4695 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
4696 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
4697 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4698 if (llvm::StringSwitch<bool>(II->getName())
4699 .Case("in", true)
4700 .Case("out", true)
4701 .Case("inout", true)
4702 .Case("oneway", true)
4703 .Case("bycopy", true)
4704 .Case("byref", true)
4705 .Default(false))
4706 Tokens[I].int_data[0] = CXToken_Keyword;
4707 continue;
4708 }
4709
4710 if (Cursors[I].kind == CXCursor_CXXMethod) {
4711 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4712 if (CXXMethodDecl *Method
4713 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
4714 if ((Method->hasAttr<FinalAttr>() ||
4715 Method->hasAttr<OverrideAttr>()) &&
4716 Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
4717 llvm::StringSwitch<bool>(II->getName())
4718 .Case("final", true)
4719 .Case("override", true)
4720 .Default(false))
4721 Tokens[I].int_data[0] = CXToken_Keyword;
4722 }
4723 continue;
4724 }
4725
4726 if (Cursors[I].kind == CXCursor_ClassDecl ||
4727 Cursors[I].kind == CXCursor_StructDecl ||
4728 Cursors[I].kind == CXCursor_ClassTemplate) {
4729 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
4730 if (II->getName() == "final") {
4731 // We have to be careful with 'final', since it could be the name
4732 // of a member class rather than the context-sensitive keyword.
4733 // So, check whether the cursor associated with this
4734 Decl *D = getCursorDecl(Cursors[I]);
4735 if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
4736 if ((Record->hasAttr<FinalAttr>()) &&
4737 Record->getIdentifier() != II)
4738 Tokens[I].int_data[0] = CXToken_Keyword;
4739 } else if (ClassTemplateDecl *ClassTemplate
4740 = dyn_cast_or_null<ClassTemplateDecl>(D)) {
4741 CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
4742 if ((Record->hasAttr<FinalAttr>()) &&
4743 Record->getIdentifier() != II)
4744 Tokens[I].int_data[0] = CXToken_Keyword;
4745 }
4746 }
4747 continue;
4748 }
4749 }
4750 }
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004751}
Douglas Gregor27b4fa92010-01-26 17:06:03 +00004752} // end: extern "C"
4753
4754//===----------------------------------------------------------------------===//
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004755// Operations for querying linkage of a cursor.
4756//===----------------------------------------------------------------------===//
4757
4758extern "C" {
4759CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
Douglas Gregor5272e802010-03-19 05:22:59 +00004760 if (!clang_isDeclaration(cursor.kind))
4761 return CXLinkage_Invalid;
4762
Ted Kremenekfb4961d2010-03-03 06:36:57 +00004763 Decl *D = cxcursor::getCursorDecl(cursor);
4764 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
4765 switch (ND->getLinkage()) {
4766 case NoLinkage: return CXLinkage_NoLinkage;
4767 case InternalLinkage: return CXLinkage_Internal;
4768 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
4769 case ExternalLinkage: return CXLinkage_External;
4770 };
4771
4772 return CXLinkage_Invalid;
4773}
4774} // end: extern "C"
4775
4776//===----------------------------------------------------------------------===//
Ted Kremenek4ed29252010-04-12 21:22:16 +00004777// Operations for querying language of a cursor.
4778//===----------------------------------------------------------------------===//
4779
4780static CXLanguageKind getDeclLanguage(const Decl *D) {
4781 switch (D->getKind()) {
4782 default:
4783 break;
4784 case Decl::ImplicitParam:
4785 case Decl::ObjCAtDefsField:
4786 case Decl::ObjCCategory:
4787 case Decl::ObjCCategoryImpl:
4788 case Decl::ObjCClass:
4789 case Decl::ObjCCompatibleAlias:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004790 case Decl::ObjCForwardProtocol:
4791 case Decl::ObjCImplementation:
4792 case Decl::ObjCInterface:
4793 case Decl::ObjCIvar:
4794 case Decl::ObjCMethod:
4795 case Decl::ObjCProperty:
4796 case Decl::ObjCPropertyImpl:
4797 case Decl::ObjCProtocol:
4798 return CXLanguage_ObjC;
4799 case Decl::CXXConstructor:
4800 case Decl::CXXConversion:
4801 case Decl::CXXDestructor:
4802 case Decl::CXXMethod:
4803 case Decl::CXXRecord:
4804 case Decl::ClassTemplate:
4805 case Decl::ClassTemplatePartialSpecialization:
4806 case Decl::ClassTemplateSpecialization:
4807 case Decl::Friend:
4808 case Decl::FriendTemplate:
4809 case Decl::FunctionTemplate:
4810 case Decl::LinkageSpec:
4811 case Decl::Namespace:
4812 case Decl::NamespaceAlias:
4813 case Decl::NonTypeTemplateParm:
4814 case Decl::StaticAssert:
Ted Kremenek4ed29252010-04-12 21:22:16 +00004815 case Decl::TemplateTemplateParm:
4816 case Decl::TemplateTypeParm:
4817 case Decl::UnresolvedUsingTypename:
4818 case Decl::UnresolvedUsingValue:
4819 case Decl::Using:
4820 case Decl::UsingDirective:
4821 case Decl::UsingShadow:
4822 return CXLanguage_CPlusPlus;
4823 }
4824
4825 return CXLanguage_C;
4826}
4827
4828extern "C" {
Douglas Gregorf757a122010-08-23 23:00:57 +00004829
4830enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
4831 if (clang_isDeclaration(cursor.kind))
4832 if (Decl *D = cxcursor::getCursorDecl(cursor)) {
4833 if (D->hasAttr<UnavailableAttr>() ||
4834 (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()))
4835 return CXAvailability_Available;
4836
4837 if (D->hasAttr<DeprecatedAttr>())
4838 return CXAvailability_Deprecated;
4839 }
4840
4841 return CXAvailability_Available;
4842}
4843
Ted Kremenek4ed29252010-04-12 21:22:16 +00004844CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
4845 if (clang_isDeclaration(cursor.kind))
4846 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
4847
4848 return CXLanguage_Invalid;
4849}
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004850
4851 /// \brief If the given cursor is the "templated" declaration
4852 /// descibing a class or function template, return the class or
4853 /// function template.
4854static Decl *maybeGetTemplateCursor(Decl *D) {
4855 if (!D)
4856 return 0;
4857
4858 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4859 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
4860 return FunTmpl;
4861
4862 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4863 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
4864 return ClassTmpl;
4865
4866 return D;
4867}
4868
Douglas Gregor0576ce72010-09-22 21:22:29 +00004869CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
4870 if (clang_isDeclaration(cursor.kind)) {
4871 if (Decl *D = getCursorDecl(cursor)) {
4872 DeclContext *DC = D->getDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004873 if (!DC)
4874 return clang_getNullCursor();
4875
4876 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4877 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004878 }
4879 }
4880
4881 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
4882 if (Decl *D = getCursorDecl(cursor))
Ted Kremenek91554282010-11-16 08:15:36 +00004883 return MakeCXCursor(D, getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004884 }
4885
4886 return clang_getNullCursor();
4887}
4888
4889CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
4890 if (clang_isDeclaration(cursor.kind)) {
4891 if (Decl *D = getCursorDecl(cursor)) {
4892 DeclContext *DC = D->getLexicalDeclContext();
Douglas Gregor7ecd19e2010-12-21 07:55:45 +00004893 if (!DC)
4894 return clang_getNullCursor();
4895
4896 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
4897 getCursorTU(cursor));
Douglas Gregor0576ce72010-09-22 21:22:29 +00004898 }
4899 }
4900
4901 // FIXME: Note that we can't easily compute the lexical context of a
4902 // statement or expression, so we return nothing.
4903 return clang_getNullCursor();
4904}
4905
Douglas Gregor99a26af2010-10-01 20:25:15 +00004906static void CollectOverriddenMethods(DeclContext *Ctx,
4907 ObjCMethodDecl *Method,
4908 llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
4909 if (!Ctx)
4910 return;
4911
4912 // If we have a class or category implementation, jump straight to the
4913 // interface.
4914 if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
4915 return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
4916
4917 ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
4918 if (!Container)
4919 return;
4920
4921 // Check whether we have a matching method at this level.
4922 if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
4923 Method->isInstanceMethod()))
4924 if (Method != Overridden) {
4925 // We found an override at this level; there is no need to look
4926 // into other protocols or categories.
4927 Methods.push_back(Overridden);
4928 return;
4929 }
4930
4931 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
4932 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
4933 PEnd = Protocol->protocol_end();
4934 P != PEnd; ++P)
4935 CollectOverriddenMethods(*P, Method, Methods);
4936 }
4937
4938 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
4939 for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
4940 PEnd = Category->protocol_end();
4941 P != PEnd; ++P)
4942 CollectOverriddenMethods(*P, Method, Methods);
4943 }
4944
4945 if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
4946 for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
4947 PEnd = Interface->protocol_end();
4948 P != PEnd; ++P)
4949 CollectOverriddenMethods(*P, Method, Methods);
4950
4951 for (ObjCCategoryDecl *Category = Interface->getCategoryList();
4952 Category; Category = Category->getNextClassCategory())
4953 CollectOverriddenMethods(Category, Method, Methods);
4954
4955 // We only look into the superclass if we haven't found anything yet.
4956 if (Methods.empty())
4957 if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
4958 return CollectOverriddenMethods(Super, Method, Methods);
4959 }
4960}
4961
4962void clang_getOverriddenCursors(CXCursor cursor,
4963 CXCursor **overridden,
4964 unsigned *num_overridden) {
4965 if (overridden)
4966 *overridden = 0;
4967 if (num_overridden)
4968 *num_overridden = 0;
4969 if (!overridden || !num_overridden)
4970 return;
4971
4972 if (!clang_isDeclaration(cursor.kind))
4973 return;
4974
4975 Decl *D = getCursorDecl(cursor);
4976 if (!D)
4977 return;
4978
4979 // Handle C++ member functions.
Ted Kremenek91554282010-11-16 08:15:36 +00004980 CXTranslationUnit TU = getCursorTU(cursor);
Douglas Gregor99a26af2010-10-01 20:25:15 +00004981 if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
4982 *num_overridden = CXXMethod->size_overridden_methods();
4983 if (!*num_overridden)
4984 return;
4985
4986 *overridden = new CXCursor [*num_overridden];
4987 unsigned I = 0;
4988 for (CXXMethodDecl::method_iterator
4989 M = CXXMethod->begin_overridden_methods(),
4990 MEnd = CXXMethod->end_overridden_methods();
4991 M != MEnd; (void)++M, ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00004992 (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00004993 return;
4994 }
4995
4996 ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
4997 if (!Method)
4998 return;
4999
5000 // Handle Objective-C methods.
5001 llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
5002 CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
5003
5004 if (Methods.empty())
5005 return;
5006
5007 *num_overridden = Methods.size();
5008 *overridden = new CXCursor [Methods.size()];
5009 for (unsigned I = 0, N = Methods.size(); I != N; ++I)
Ted Kremenek91554282010-11-16 08:15:36 +00005010 (*overridden)[I] = MakeCXCursor(Methods[I], TU);
Douglas Gregor99a26af2010-10-01 20:25:15 +00005011}
5012
5013void clang_disposeOverriddenCursors(CXCursor *overridden) {
5014 delete [] overridden;
5015}
5016
Douglas Gregor796d76a2010-10-20 22:00:55 +00005017CXFile clang_getIncludedFile(CXCursor cursor) {
5018 if (cursor.kind != CXCursor_InclusionDirective)
5019 return 0;
5020
5021 InclusionDirective *ID = getCursorInclusionDirective(cursor);
5022 return (void *)ID->getFile();
5023}
5024
Ted Kremenek4ed29252010-04-12 21:22:16 +00005025} // end: extern "C"
5026
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005027
5028//===----------------------------------------------------------------------===//
5029// C++ AST instrospection.
5030//===----------------------------------------------------------------------===//
5031
5032extern "C" {
5033unsigned clang_CXXMethod_isStatic(CXCursor C) {
5034 if (!clang_isDeclaration(C.kind))
5035 return 0;
Douglas Gregorf11309e2010-08-31 22:12:17 +00005036
5037 CXXMethodDecl *Method = 0;
5038 Decl *D = cxcursor::getCursorDecl(C);
5039 if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5040 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5041 else
5042 Method = dyn_cast_or_null<CXXMethodDecl>(D);
5043 return (Method && Method->isStatic()) ? 1 : 0;
Ted Kremenek0ed75492010-05-17 20:12:45 +00005044}
Ted Kremeneka10f1282010-05-18 22:32:15 +00005045
Ted Kremenek9cfe9e62010-05-17 20:06:56 +00005046} // end: extern "C"
5047
Ted Kremenek4ed29252010-04-12 21:22:16 +00005048//===----------------------------------------------------------------------===//
Ted Kremeneka5940822010-08-26 01:42:22 +00005049// Attribute introspection.
5050//===----------------------------------------------------------------------===//
5051
5052extern "C" {
5053CXType clang_getIBOutletCollectionType(CXCursor C) {
5054 if (C.kind != CXCursor_IBOutletCollectionAttr)
Ted Kremenek91554282010-11-16 08:15:36 +00005055 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005056
5057 IBOutletCollectionAttr *A =
5058 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
5059
Douglas Gregorc81a7a22011-03-06 18:55:32 +00005060 return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
Ted Kremeneka5940822010-08-26 01:42:22 +00005061}
5062} // end: extern "C"
5063
5064//===----------------------------------------------------------------------===//
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005065// Misc. utility functions.
5066//===----------------------------------------------------------------------===//
Ted Kremenekf441baf2010-02-17 00:41:40 +00005067
Daniel Dunbar087c3a32010-11-05 17:21:46 +00005068/// Default to using an 8 MB stack size on "safety" threads.
5069static unsigned SafetyStackThreadSize = 8 << 20;
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005070
5071namespace clang {
5072
5073bool RunSafely(llvm::CrashRecoveryContext &CRC,
Ted Kremenekca817a3c2010-11-14 17:47:35 +00005074 void (*Fn)(void*), void *UserData,
5075 unsigned Size) {
5076 if (!Size)
5077 Size = GetSafetyThreadStackSize();
5078 if (Size)
Daniel Dunbarb7383e62010-11-05 07:19:31 +00005079 return CRC.RunSafelyOnThread(Fn, UserData, Size);
5080 return CRC.RunSafely(Fn, UserData);
5081}
5082
5083unsigned GetSafetyThreadStackSize() {
5084 return SafetyStackThreadSize;
5085}
5086
5087void SetSafetyThreadStackSize(unsigned Value) {
5088 SafetyStackThreadSize = Value;
5089}
5090
5091}
5092
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005093extern "C" {
5094
Ted Kremeneka3e65702010-02-12 22:54:40 +00005095CXString clang_getClangVersion() {
Ted Kremenek5cca6eb2010-02-17 00:41:08 +00005096 return createCXString(getClangFullVersion());
Ted Kremenekc0f3f722010-01-22 22:44:15 +00005097}
5098
5099} // end: extern "C"