CIndex.cpp revision a64ccefdf0ea4e03ec88805d71b0af74950c7472
1d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//
3d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//                     The LLVM Compiler Infrastructure
4d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//
5d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// This file is distributed under the University of Illinois Open Source
6d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// License. See LICENSE.TXT for details.
70d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar//
8d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//===----------------------------------------------------------------------===//
9d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//
10ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// This file implements the main API hooks in the Clang-C Source Indexing
11ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// library.
12d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//
13d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//===----------------------------------------------------------------------===//
14d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek
15ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "CIndexer.h"
1616c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "CXCursor.h"
170a90d32523bfe5fa63e11b648686c9699f786d15Ted Kremenek#include "CXTranslationUnit.h"
18ed122735639d83c10f18c28c7fd117bfcd0f62cbTed Kremenek#include "CXString.h"
1995f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek#include "CXType.h"
20a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek#include "CXSourceLocation.h"
215352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor#include "CIndexDiagnostic.h"
22ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
2304bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek#include "clang/Basic/Version.h"
24936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor
2550398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff#include "clang/AST/DeclVisitor.h"
26fb5704295c6137685a7b90b92cd6b958028740c8Steve Naroff#include "clang/AST/StmtVisitor.h"
277d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor#include "clang/AST/TypeLocVisitor.h"
28b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Basic/Diagnostic.h"
29b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/ASTUnit.h"
30b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/CompilerInstance.h"
31936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor#include "clang/Frontend/FrontendDiagnostic.h"
32d8210650ed948de65a08a8daf16d291b747717c4Ted Kremenek#include "clang/Lex/Lexer.h"
33dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor#include "clang/Lex/HeaderSearch.h"
34b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Lex/PreprocessingRecord.h"
3533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor#include "clang/Lex/Preprocessor.h"
36a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor#include "llvm/ADT/STLExtras.h"
37d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek#include "llvm/ADT/Optional.h"
38f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor#include "llvm/ADT/StringSwitch.h"
39d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek#include "clang/Analysis/Support/SaveAndRestore.h"
40c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar#include "llvm/Support/CrashRecoveryContext.h"
4148615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar#include "llvm/Support/PrettyStackTrace.h"
4202465750c8c3fa96b1e7e596b02297e24361dc4fDouglas Gregor#include "llvm/Support/MemoryBuffer.h"
43358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor#include "llvm/Support/raw_ostream.h"
447a07fcb8f10fe45ea65a0a41798eb1c40777bde4Douglas Gregor#include "llvm/Support/Timer.h"
4503013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Mutex.h"
4603013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Program.h"
4703013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Signals.h"
4803013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Threading.h"
4937f1ea0eb08a00fa90edbecb427cfbb50ca0f4d0Ted Kremenek#include "llvm/Support/Compiler.h"
50fc0622155fa61349698a8fd0053773c37d9f7ac4Ted Kremenek
5150398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroffusing namespace clang;
5216c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenekusing namespace clang::cxcursor;
53ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenekusing namespace clang::cxstring;
5450398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff
55a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenekstatic CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) {
56a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  if (!TU)
57a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    return 0;
58a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  CXTranslationUnit D = new CXTranslationUnitImpl();
59a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  D->TUData = TU;
60a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  D->StringPool = createCXStringPool();
61a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  return D;
62a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek}
63a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek
6433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \brief The result of comparing two source ranges.
6533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregorenum RangeComparisonResult {
6633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// \brief Either the ranges overlap or one of the ranges is invalid.
6733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  RangeOverlap,
68f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
6933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// \brief The first range ends before the second range starts.
7033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  RangeBefore,
71f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
7233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// \brief The first range starts after the second range ends.
7333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  RangeAfter
7433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor};
7533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor
76f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek/// \brief Compare two source ranges to determine their relative position in
7733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// the translation unit.
78f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekstatic RangeComparisonResult RangeCompare(SourceManager &SM,
79f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek                                          SourceRange R1,
8033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor                                          SourceRange R2) {
8133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  assert(R1.isValid() && "First range is invalid?");
8233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  assert(R2.isValid() && "Second range is invalid?");
83a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  if (R1.getEnd() != R2.getBegin() &&
84d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar      SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
8533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor    return RangeBefore;
86a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  if (R2.getEnd() != R1.getBegin() &&
87d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar      SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
8833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor    return RangeAfter;
8933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  return RangeOverlap;
9033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor}
9133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor
92fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek/// \brief Determine if a source location falls within, before, or after a
93fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek///   a given source range.
94fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekstatic RangeComparisonResult LocationCompare(SourceManager &SM,
95fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek                                             SourceLocation L, SourceRange R) {
96fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  assert(R.isValid() && "First range is invalid?");
97fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  assert(L.isValid() && "Second range is invalid?");
98a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  if (L == R.getBegin() || L == R.getEnd())
99fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    return RangeOverlap;
100fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
101fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    return RangeBefore;
102fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
103fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    return RangeAfter;
104fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  return RangeOverlap;
105fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek}
106fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
10776dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// \brief Translate a Clang source range into a CIndex source range.
10876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar///
10976dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// Clang internally represents ranges where the end location points to the
11076dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// start of the token at the end. However, for external clients it is more
11176dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// useful to have a CXSourceRange be a proper half-open interval. This routine
11276dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// does the appropriate translation.
113f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed KremenekCXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
11476dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar                                          const LangOptions &LangOpts,
1150a76aae8c03cb7dd7bdbe683485560afaf695959Chris Lattner                                          const CharSourceRange &R) {
11676dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar  // We want the last character in this location, so we will adjust the
1176a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor  // location accordingly.
11876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar  SourceLocation EndLoc = R.getEnd();
119a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  if (EndLoc.isValid() && EndLoc.isMacroID())
120edc3dccece244a584f8ebdb81da6c962c08e79beChandler Carruth    EndLoc = SM.getExpansionRange(EndLoc).second;
1210a76aae8c03cb7dd7bdbe683485560afaf695959Chris Lattner  if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
1226a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor    unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
123a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis    EndLoc = EndLoc.getLocWithOffset(Length);
12476dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar  }
12576dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar
12676dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar  CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
12776dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar                           R.getBegin().getRawEncoding(),
12876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar                           EndLoc.getRawEncoding() };
12976dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar  return Result;
13076dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar}
1311db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor
1328a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek//===----------------------------------------------------------------------===//
13333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor// Cursor visitor.
1348a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek//===----------------------------------------------------------------------===//
1358a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek
13689922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroffnamespace {
137c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
138c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekclass VisitorJob {
139c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekpublic:
140cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek  enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
141e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek              TypeLocVisitKind, OverloadExprPartsKind,
14260608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek              DeclRefExprPartsKind, LabelRefVisitKind,
143f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek              ExplicitTemplateArgsVisitKind,
144f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor              NestedNameSpecifierLocVisitKind,
145cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek              DeclarationNameInfoVisitKind,
14694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor              MemberRefVisitKind, SizeOfPackExprPartsKind };
147c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekprotected:
148f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  void *data[3];
149c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  CXCursor parent;
150c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  Kind K;
151f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
152f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    : parent(C), K(k) {
153f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    data[0] = d1;
154f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    data[1] = d2;
155f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    data[2] = d3;
156f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  }
157c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekpublic:
158c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  Kind getKind() const { return K; }
159c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  const CXCursor &getParent() const { return parent; }
160c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  static bool classof(VisitorJob *VJ) { return true; }
161c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek};
162c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
1635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnertypedef SmallVector<VisitorJob, 10> VisitorWorkList;
164c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
165b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor// Cursor visitor.
1667d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorclass CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
167cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek                      public TypeLocVisitor<CursorVisitor, bool>
1687d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor{
16933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// \brief The translation unit we are traversing.
170a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  CXTranslationUnit TU;
171a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *AU;
172f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
17333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// \brief The parent cursor whose children we are traversing.
174b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  CXCursor Parent;
175f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
17633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// \brief The declaration that serves at the parent of any statement or
17733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// expression nodes.
178f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  Decl *StmtParent;
179f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
18033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// \brief The visitor function.
181b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  CXCursorVisitor Visitor;
182f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
18333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// \brief The opaque client data, to be passed along to the visitor.
184b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  CXClientData ClientData;
185f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
18604a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor  /// \brief Whether we should visit the preprocessing record entries last,
18704a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor  /// after visiting other declarations.
18804a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor  bool VisitPreprocessorLast;
18904a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor
19033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// \brief When valid, a source range to which the cursor should restrict
19133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  /// its search.
19233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  SourceRange RegionOfInterest;
193f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
194d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // FIXME: Eventually remove.  This part of a hack to support proper
195d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // iteration over all Decls contained lexically within an ObjC container.
196d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  DeclContext::decl_iterator *DI_current;
197d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  DeclContext::decl_iterator DE_current;
198d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek
199d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  // Cache of pre-allocated worklists for data-recursion walk of Stmts.
2005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<VisitorWorkList*, 5> WorkListFreeList;
2015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<VisitorWorkList*, 5> WorkListCache;
202d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek
203b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  using DeclVisitor<CursorVisitor, bool>::Visit;
2047d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor  using TypeLocVisitor<CursorVisitor, bool>::Visit;
205f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
206f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  /// \brief Determine whether this particular source range comes before, comes
207f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  /// after, or overlaps the region of interest.
20833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  ///
209d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar  /// \param R a half-open source range retrieved from the abstract syntax tree.
210f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  RangeComparisonResult CompareRegionOfInterest(SourceRange R);
211f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
2120f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek  class SetParentRAII {
2130f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek    CXCursor &Parent;
2140f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek    Decl *&StmtParent;
2150f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek    CXCursor OldParent;
2160f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek
2170f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek  public:
2180f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek    SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
2190f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek      : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
2200f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek    {
2210f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek      Parent = NewParent;
2220f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek      if (clang_isDeclaration(Parent.kind))
2230f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek        StmtParent = getCursorDecl(Parent);
2240f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek    }
2250f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek
2260f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek    ~SetParentRAII() {
2270f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek      Parent = OldParent;
2280f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek      if (clang_isDeclaration(Parent.kind))
2290f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek        StmtParent = getCursorDecl(Parent);
2300f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek    }
2310f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek  };
2320f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek
233b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorpublic:
234a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
235a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                CXClientData ClientData,
23604a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor                bool VisitPreprocessorLast,
23733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor                SourceRange RegionOfInterest = SourceRange())
238a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
239a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      Visitor(Visitor), ClientData(ClientData),
24008e0bc16b3312c27e87d33be7dcf3d4fe5bdd2e2Douglas Gregor      VisitPreprocessorLast(VisitPreprocessorLast),
24104a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor      RegionOfInterest(RegionOfInterest), DI_current(0)
242b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  {
243b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    Parent.kind = CXCursor_NoDeclFound;
244b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    Parent.data[0] = 0;
245b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    Parent.data[1] = 0;
246b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    Parent.data[2] = 0;
247f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    StmtParent = 0;
248b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  }
249f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
250d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  ~CursorVisitor() {
251d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek    // Free the pre-allocated worklists for data-recursion.
2525f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    for (SmallVectorImpl<VisitorWorkList*>::iterator
253d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek          I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
254d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek      delete *I;
255d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek    }
256d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  }
257d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek
258a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
259a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  CXTranslationUnit getTU() const { return TU; }
260ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek
26133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
262788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
2634c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  bool visitPreprocessedEntitiesInRegion();
2644c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
2654c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  template<typename InputIterator>
2664c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  bool visitPreprocessedEntitiesInRegion(InputIterator First,
2674c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor                                         InputIterator Last);
2684c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
2694c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  template<typename InputIterator>
2704c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  bool visitPreprocessedEntities(InputIterator First, InputIterator Last);
271788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
272b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  bool VisitChildren(CXCursor Parent);
273f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
2747d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor  // Declaration visitors
275162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  bool VisitTypeAliasDecl(TypeAliasDecl *D);
27609dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek  bool VisitAttributes(Decl *D);
2771ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek  bool VisitBlockDecl(BlockDecl *B);
2783064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek  bool VisitCXXRecordDecl(CXXRecordDecl *D);
279d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  llvm::Optional<bool> shouldVisitCursor(CXCursor C);
280b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  bool VisitDeclContext(DeclContext *DC);
28179758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
28279758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitTypedefDecl(TypedefDecl *D);
28379758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitTagDecl(TagDecl *D);
2840ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
28574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor  bool VisitClassTemplatePartialSpecializationDecl(
28674dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor                                     ClassTemplatePartialSpecializationDecl *D);
287fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
2884540c9c73787d6ef736792f24209727b64997c90Ted Kremenek  bool VisitEnumConstantDecl(EnumConstantDecl *D);
28979758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitDeclaratorDecl(DeclaratorDecl *DD);
2904540c9c73787d6ef736792f24209727b64997c90Ted Kremenek  bool VisitFunctionDecl(FunctionDecl *ND);
29179758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitFieldDecl(FieldDecl *D);
29279758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitVarDecl(VarDecl *);
29384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor  bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
294fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
29539d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor  bool VisitClassTemplateDecl(ClassTemplateDecl *D);
29684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor  bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
29779758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
2984540c9c73787d6ef736792f24209727b64997c90Ted Kremenek  bool VisitObjCContainerDecl(ObjCContainerDecl *D);
29979758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
30079758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
30123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
30279758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
3034540c9c73787d6ef736792f24209727b64997c90Ted Kremenek  bool VisitObjCImplDecl(ObjCImplDecl *D);
30479758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
3051ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
30679758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
30779758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
30879758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek  bool VisitObjCClassDecl(ObjCClassDecl *D);
309a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
310a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek  bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
3118f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek  bool VisitNamespaceDecl(NamespaceDecl *D);
3126931900f43cea558c6974075256c07728dbfecc6Douglas Gregor  bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
3130a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor  bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
3147e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor  bool VisitUsingDecl(UsingDecl *D);
3157e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor  bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
3167e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor  bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
3170a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor
31801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  // Name visitor
31901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
320c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
321dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
32201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
323fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  // Template visitors
324fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  bool VisitTemplateParameters(const TemplateParameterList *Params);
3250b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
326fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
327fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
3287d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor  // Type visitors
329427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis#define ABSTRACT_TYPELOC(CLASS, PARENT)
330427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis#define TYPELOC(CLASS, PARENT) \
331427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis  bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
332427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis#include "clang/AST/TypeLocNodes.def"
333427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis
334f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  bool VisitTagTypeLoc(TagTypeLoc TL);
335f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  bool VisitArrayTypeLoc(ArrayTypeLoc TL);
336427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis  bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
337427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis
338c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  // Data-recursive visitor functions.
339c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  bool IsInRegionOfInterest(CXCursor C);
340c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  bool RunVisitorWorkList(VisitorWorkList &WL);
341c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
342cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
343b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor};
344f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
345b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} // end anonymous namespace
3460d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar
347a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorstatic SourceRange getRawCursorExtent(CXCursor C);
3486653798ff5ce6deb58112777e21307ccc453133dDouglas Gregorstatic SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
3496653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor
350a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor
35133e9abd21083a0191a7676a04b497006d2da184dDouglas GregorRangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
352a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
35333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor}
35433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor
355b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \brief Visit the given cursor and, if requested by the visitor,
356b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// its children.
357b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor///
35833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \param Cursor the cursor to visit.
35933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor///
36033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \param CheckRegionOfInterest if true, then the caller already checked that
36133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// this cursor is within the region of interest.
36233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor///
363b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \returns true if the visitation should be aborted, false if it
364b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// should continue.
36533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregorbool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
366b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  if (clang_isInvalid(Cursor.kind))
367b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    return false;
368f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
369b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  if (clang_isDeclaration(Cursor.kind)) {
370b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    Decl *D = getCursorDecl(Cursor);
371b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    assert(D && "Invalid declaration cursor");
372b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    if (D->isImplicit())
373b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor      return false;
374b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  }
3750d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar
37633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  // If we have a range of interest, and this cursor doesn't intersect with it,
37733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  // we're done.
37833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
379a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor    SourceRange Range = getRawCursorExtent(Cursor);
380f408f32aa9ae3d97bc656267dc5d78fa7d03499bDaniel Dunbar    if (Range.isInvalid() || CompareRegionOfInterest(Range))
38133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor      return false;
38233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  }
383f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
384b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  switch (Visitor(Cursor, Parent, ClientData)) {
385b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  case CXChildVisit_Break:
386b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    return true;
3870d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar
388b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  case CXChildVisit_Continue:
389b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    return false;
3902e331b938b38057e333fab0ba841130ea8467794Douglas Gregor
391b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  case CXChildVisit_Recurse:
392b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    return VisitChildren(Cursor);
393b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  }
3940d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar
395fd64377225a6a140bddb3f997d52a036486f9360Douglas Gregor  return false;
396b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor}
3970d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar
3984c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregorbool CursorVisitor::visitPreprocessedEntitiesInRegion() {
399788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  PreprocessingRecord &PPRec
400a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    = *AU->getPreprocessor().getPreprocessingRecord();
401788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
402788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  bool OnlyLocalDecls
40332038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor    = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
40432038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor
40532038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor  if (OnlyLocalDecls && RegionOfInterest.isValid()) {
40632038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor    // If we would only look at local declarations but we have a region of
40732038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor    // interest, check whether that region of interest is in the main file.
40832038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor    // If not, we should traverse all declarations.
40932038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor    // FIXME: My kingdom for a proper binary search approach to finding
41032038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor    // cursors!
41132038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor    std::pair<FileID, unsigned> Location
412e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth      = AU->getSourceManager().getDecomposedExpansionLoc(
41332038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor                                                   RegionOfInterest.getBegin());
41432038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor    if (Location.first != AU->getSourceManager().getMainFileID())
41532038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor      OnlyLocalDecls = false;
41632038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor  }
417788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
41889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor  PreprocessingRecord::iterator StartEntity, EndEntity;
4194c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  if (OnlyLocalDecls && AU->pp_entity_begin() != AU->pp_entity_end())
4204c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    return visitPreprocessedEntitiesInRegion(AU->pp_entity_begin(),
4214c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor                                      AU->pp_entity_end());
4224c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  else
4234c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    return visitPreprocessedEntitiesInRegion(PPRec.begin(), PPRec.end());
4244c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor}
4254c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
4264c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregortemplate<typename InputIterator>
4274c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregorbool CursorVisitor::visitPreprocessedEntitiesInRegion(InputIterator First,
4284c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor                                                      InputIterator Last) {
429788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  // There is no region of interest; we have to walk everything.
430788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  if (RegionOfInterest.isInvalid())
4314c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    return visitPreprocessedEntities(First, Last);
4324c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
433788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  // Find the file in which the region of interest lands.
434a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  SourceManager &SM = AU->getSourceManager();
435788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  std::pair<FileID, unsigned> Begin
436e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth    = SM.getDecomposedExpansionLoc(RegionOfInterest.getBegin());
437788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  std::pair<FileID, unsigned> End
438e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth    = SM.getDecomposedExpansionLoc(RegionOfInterest.getEnd());
439788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
440788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  // The region of interest spans files; we have to walk everything.
441788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  if (Begin.first != End.first)
4424c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    return visitPreprocessedEntities(First, Last);
4434c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
444788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
4454c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  = AU->getPreprocessedEntitiesByFile();
446788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  if (ByFileMap.empty()) {
447788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor    // Build the mapping from files to sets of preprocessed entities.
4484c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    for (; First != Last; ++First) {
449788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor      std::pair<FileID, unsigned> P
450e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth        = SM.getDecomposedExpansionLoc((*First)->getSourceRange().getBegin());
4514c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
4524c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor      ByFileMap[P.first].push_back(*First);
4534c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    }
4544c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  }
4554c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
4564c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  return visitPreprocessedEntities(ByFileMap[Begin.first].begin(),
4574c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor                                   ByFileMap[Begin.first].end());
4584c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor}
4594c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
4604c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregortemplate<typename InputIterator>
4614c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregorbool CursorVisitor::visitPreprocessedEntities(InputIterator First,
4624c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor                                              InputIterator Last) {
4634c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  for (; First != Last; ++First) {
4644c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    if (MacroExpansion *ME = dyn_cast<MacroExpansion>(*First)) {
4654c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor      if (Visit(MakeMacroExpansionCursor(ME, TU)))
4664c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor        return true;
4674c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
4684c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor      continue;
4694c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    }
4704c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
4714c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*First)) {
4724c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor      if (Visit(MakeMacroDefinitionCursor(MD, TU)))
4734c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor        return true;
47489d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor
4754c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor      continue;
4764c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    }
4774c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
4784c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor    if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*First)) {
4794c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor      if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
4804c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor        return true;
4814c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor
4824c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor      continue;
483788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor    }
484788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor  }
485788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
4864c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor  return false;
487788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor}
488788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor
489b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \brief Visit the children of the given cursor.
490a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek///
491b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \returns true if the visitation should be aborted, false if it
492b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// should continue.
493f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekbool CursorVisitor::VisitChildren(CXCursor Cursor) {
494c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor  if (clang_isReference(Cursor.kind) &&
495c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor      Cursor.kind != CXCursor_CXXBaseSpecifier) {
496a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor    // By definition, references have no children.
497a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor    return false;
498a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor  }
499f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
500f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  // Set the Parent field to Cursor, then back to its old value once we're
501b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  // done.
5020f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek  SetParentRAII SetParent(Parent, StmtParent, Cursor);
503f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
504b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  if (clang_isDeclaration(Cursor.kind)) {
505b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    Decl *D = getCursorDecl(Cursor);
50606d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor    if (!D)
50706d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor      return false;
50806d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor
509539311e0221df256c70c1c3080c8af847cd29dffTed Kremenek    return VisitAttributes(D) || Visit(D);
510b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  }
511f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
51206d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor  if (clang_isStatement(Cursor.kind)) {
51306d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor    if (Stmt *S = getCursorStmt(Cursor))
51406d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor      return Visit(S);
51506d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor
51606d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor    return false;
51706d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor  }
51806d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor
51906d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor  if (clang_isExpression(Cursor.kind)) {
52006d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor    if (Expr *E = getCursorExpr(Cursor))
52106d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor      return Visit(E);
52206d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor
52306d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor    return false;
52406d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor  }
525f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
526b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  if (clang_isTranslationUnit(Cursor.kind)) {
527a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    CXTranslationUnit tu = getCursorTU(Cursor);
528a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
52904a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor
53004a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor    int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
53104a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor    for (unsigned I = 0; I != 2; ++I) {
53204a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor      if (VisitOrder[I]) {
53304a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor        if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
53404a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor            RegionOfInterest.isInvalid()) {
53504a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor          for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
53604a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor                                        TLEnd = CXXUnit->top_level_end();
53704a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor               TL != TLEnd; ++TL) {
53804a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor            if (Visit(MakeCXCursor(*TL, tu), true))
53904a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor              return true;
54004a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor          }
54104a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor        } else if (VisitDeclContext(
54204a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor                                CXXUnit->getASTContext().getTranslationUnitDecl()))
5437b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor          return true;
54404a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor        continue;
5457b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor      }
5463178cb674ac8c3b59e1791e14d38d48619a1b621Bob Wilson
54704a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor      // Walk the preprocessing record.
5484c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor      if (CXXUnit->getPreprocessor().getPreprocessingRecord())
5494c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor        visitPreprocessedEntitiesInRegion();
5500396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor    }
55104a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor
5527b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor    return false;
553b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  }
554f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
555c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor  if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
556c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor    if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
557c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor      if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
558c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor        return Visit(BaseTSInfo->getTypeLoc());
559c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor      }
560c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor    }
561c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor  }
562221d5a5005b3dbde50b8b0a40bb5c5e6da8c1173Argyrios Kyrtzidis
563221d5a5005b3dbde50b8b0a40bb5c5e6da8c1173Argyrios Kyrtzidis  if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
564221d5a5005b3dbde50b8b0a40bb5c5e6da8c1173Argyrios Kyrtzidis    IBOutletCollectionAttr *A =
565221d5a5005b3dbde50b8b0a40bb5c5e6da8c1173Argyrios Kyrtzidis      cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
566221d5a5005b3dbde50b8b0a40bb5c5e6da8c1173Argyrios Kyrtzidis    if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
567221d5a5005b3dbde50b8b0a40bb5c5e6da8c1173Argyrios Kyrtzidis      return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
568221d5a5005b3dbde50b8b0a40bb5c5e6da8c1173Argyrios Kyrtzidis                                                    A->getInterfaceLoc(), TU));
569221d5a5005b3dbde50b8b0a40bb5c5e6da8c1173Argyrios Kyrtzidis  }
570221d5a5005b3dbde50b8b0a40bb5c5e6da8c1173Argyrios Kyrtzidis
571b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  // Nothing to visit at the moment.
572b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  return false;
573dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek}
574dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek
5751ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenekbool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
57613c8ccb59b38e9e7133f1c80a00f210b6514a0b1Douglas Gregor  if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
57713c8ccb59b38e9e7133f1c80a00f210b6514a0b1Douglas Gregor    if (Visit(TSInfo->getTypeLoc()))
57813c8ccb59b38e9e7133f1c80a00f210b6514a0b1Douglas Gregor        return true;
5791ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek
580664cffd330611d78fc0286f539589920a37ca328Ted Kremenek  if (Stmt *Body = B->getBody())
581664cffd330611d78fc0286f539589920a37ca328Ted Kremenek    return Visit(MakeCXCursor(Body, StmtParent, TU));
582664cffd330611d78fc0286f539589920a37ca328Ted Kremenek
583664cffd330611d78fc0286f539589920a37ca328Ted Kremenek  return false;
5841ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek}
5851ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek
586d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenekllvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
587d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  if (RegionOfInterest.isValid()) {
5886653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
589d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    if (Range.isInvalid())
590d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      return llvm::Optional<bool>();
5916653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor
592d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    switch (CompareRegionOfInterest(Range)) {
593d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    case RangeBefore:
594d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      // This declaration comes before the region of interest; skip it.
595d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      return llvm::Optional<bool>();
59623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek
597d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    case RangeAfter:
598d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      // This declaration comes after the region of interest; we're done.
599d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      return false;
600d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar
601d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    case RangeOverlap:
602d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      // This declaration overlaps the region of interest; visit it.
603d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      break;
604d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    }
605d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  }
606d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  return true;
607d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek}
608f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
609d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenekbool CursorVisitor::VisitDeclContext(DeclContext *DC) {
610d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
611f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
612d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // FIXME: Eventually remove.  This part of a hack to support proper
613d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // iteration over all Decls contained lexically within an ObjC container.
614d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
615d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
616f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
617d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  for ( ; I != E; ++I) {
618d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    Decl *D = *I;
619d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    if (D->getLexicalDeclContext() != DC)
620d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      continue;
621d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    CXCursor Cursor = MakeCXCursor(D, TU);
622d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
623d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    if (!V.hasValue())
624d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      continue;
625d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    if (!V.getValue())
626d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      return false;
627d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar    if (Visit(Cursor, true))
628b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor      return true;
629b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  }
630b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  return false;
631dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek}
632dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek
6331ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
6341ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  llvm_unreachable("Translation units are visited directly by Visit()");
6351ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return false;
6361ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor}
6371ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor
638162e1c1b487352434552147967c3dd296ebee2f7Richard Smithbool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
639162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
640162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    return Visit(TSInfo->getTypeLoc());
641162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
642162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  return false;
643162e1c1b487352434552147967c3dd296ebee2f7Richard Smith}
644162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
6451ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
6461ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
6471ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor    return Visit(TSInfo->getTypeLoc());
648f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
6491ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return false;
6501ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor}
6511ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor
6521ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTagDecl(TagDecl *D) {
6531ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return VisitDeclContext(D);
6541ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor}
6551ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor
6560ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregorbool CursorVisitor::VisitClassTemplateSpecializationDecl(
6570ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor                                          ClassTemplateSpecializationDecl *D) {
6580ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  bool ShouldVisitBody = false;
6590ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  switch (D->getSpecializationKind()) {
6600ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  case TSK_Undeclared:
6610ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  case TSK_ImplicitInstantiation:
6620ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor    // Nothing to visit
6630ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor    return false;
6640ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor
6650ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  case TSK_ExplicitInstantiationDeclaration:
6660ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  case TSK_ExplicitInstantiationDefinition:
6670ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor    break;
6680ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor
6690ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  case TSK_ExplicitSpecialization:
6700ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor    ShouldVisitBody = true;
6710ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor    break;
6720ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  }
6730ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor
6740ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  // Visit the template arguments used in the specialization.
6750ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
6760ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor    TypeLoc TL = SpecType->getTypeLoc();
6770ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor    if (TemplateSpecializationTypeLoc *TSTLoc
6780ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor          = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
6790ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor      for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
6800ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor        if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
6810ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor          return true;
6820ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor    }
6830ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  }
6840ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor
6850ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  if (ShouldVisitBody && VisitCXXRecordDecl(D))
6860ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor    return true;
6870ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor
6880ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor  return false;
6890ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor}
6900ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor
69174dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregorbool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
69274dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor                                   ClassTemplatePartialSpecializationDecl *D) {
69374dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor  // FIXME: Visit the "outer" template parameter lists on the TagDecl
69474dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor  // before visiting these template parameters.
69574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor  if (VisitTemplateParameters(D->getTemplateParameters()))
69674dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor    return true;
69774dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor
69874dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor  // Visit the partial specialization arguments.
69974dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor  const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
70074dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor  for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
70174dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor    if (VisitTemplateArgumentLoc(TemplateArgs[I]))
70274dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor      return true;
70374dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor
70474dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor  return VisitCXXRecordDecl(D);
70574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor}
70674dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor
707fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
70884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor  // Visit the default argument.
70984b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
71084b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor    if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
71184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor      if (Visit(DefArg->getTypeLoc()))
71284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor        return true;
71384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor
714fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  return false;
715fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor}
716fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
7171ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
7181ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  if (Expr *Init = D->getInitExpr())
7191ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor    return Visit(MakeCXCursor(Init, StmtParent, TU));
7201ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return false;
7211ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor}
7221ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor
7237d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorbool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
7247d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor  if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
7257d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor    if (Visit(TSInfo->getTypeLoc()))
7267d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor      return true;
7277d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor
728c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  // Visit the nested-name-specifier, if present.
729c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
730c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    if (VisitNestedNameSpecifierLoc(QualifierLoc))
731c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      return true;
732c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor
7337d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor  return false;
7347d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor}
7357d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor
736a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor/// \brief Compare two base or member initializers based on their source order.
737cbb67480094b3bcb5b715acd827cbad55e2a204cSean Huntstatic int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
738cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  CXXCtorInitializer const * const *X
739cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt    = static_cast<CXXCtorInitializer const * const *>(Xp);
740cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  CXXCtorInitializer const * const *Y
741cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt    = static_cast<CXXCtorInitializer const * const *>(Yp);
742a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
743a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor  if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
744a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    return -1;
745a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor  else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
746a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    return 1;
747a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor  else
748a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    return 0;
749a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor}
750a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
751b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
75201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
75301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    // Visit the function declaration's syntactic components in the order
75401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    // written. This requires a bit of work.
755723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara    TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
75601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
75701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
75801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    // If we have a function declared directly (without the use of a typedef),
75901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    // visit just the return type. Otherwise, just visit the function's type
76001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    // now.
76101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
76201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor        (!FTL && Visit(TL)))
76301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor      return true;
76401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
765c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    // Visit the nested-name-specifier, if present.
766c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
767c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      if (VisitNestedNameSpecifierLoc(QualifierLoc))
768c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor        return true;
76901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
77001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    // Visit the declaration name.
77101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    if (VisitDeclarationNameInfo(ND->getNameInfo()))
77201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor      return true;
77301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
77401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    // FIXME: Visit explicitly-specified template arguments!
77501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
77601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    // Visit the function parameters, if we have a function type.
77701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    if (FTL && VisitFunctionTypeLoc(*FTL, true))
77801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor      return true;
77901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
78001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    // FIXME: Attributes?
78101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  }
78201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
78310620eb5164e31208fcbf0437cd79ae535ed0559Sean Hunt  if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
784a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
785a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      // Find the initializers that were written in the source.
7865f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner      SmallVector<CXXCtorInitializer *, 4> WrittenInits;
787a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
788a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor                                          IEnd = Constructor->init_end();
789a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor           I != IEnd; ++I) {
790a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor        if (!(*I)->isWritten())
791a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor          continue;
792a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
793a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor        WrittenInits.push_back(*I);
794a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      }
795a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
796a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      // Sort the initializers in source order
797a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
798cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt                           &CompareCXXCtorInitializers);
799a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
800a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      // Visit the initializers in source order
801a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
802cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt        CXXCtorInitializer *Init = WrittenInits[I];
80300eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet        if (Init->isAnyMemberInitializer()) {
80400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet          if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
805a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor                                        Init->getMemberLocation(), TU)))
806a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor            return true;
807a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor        } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) {
808a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor          if (Visit(BaseInfo->getTypeLoc()))
809a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor            return true;
810a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor        }
811a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
812a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor        // Visit the initializer value.
813a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor        if (Expr *Initializer = Init->getInit())
814a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor          if (Visit(MakeCXCursor(Initializer, ND, TU)))
815a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor            return true;
816a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      }
817a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    }
818a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
819a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
820a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      return true;
821a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor  }
822f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
823b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  return false;
824b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor}
825dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek
8261ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
8271ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  if (VisitDeclaratorDecl(D))
8281ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor    return true;
829f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
8301ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  if (Expr *BitWidth = D->getBitWidth())
8311ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor    return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
832f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
8331ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return false;
8341ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor}
8351ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor
8361ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitVarDecl(VarDecl *D) {
8371ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  if (VisitDeclaratorDecl(D))
8381ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor    return true;
839f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
8401ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  if (Expr *Init = D->getInit())
8411ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor    return Visit(MakeCXCursor(Init, StmtParent, TU));
842f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
8431ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return false;
8441ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor}
8451ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor
84684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregorbool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
84784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor  if (VisitDeclaratorDecl(D))
84884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor    return true;
84984b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor
85084b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
85184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor    if (Expr *DefArg = D->getDefaultArgument())
85284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor      return Visit(MakeCXCursor(DefArg, StmtParent, TU));
85384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor
85484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor  return false;
85584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor}
85684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor
857fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
858fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
859fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  // before visiting these template parameters.
860fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  if (VisitTemplateParameters(D->getTemplateParameters()))
861fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return true;
862fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
863fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  return VisitFunctionDecl(D->getTemplatedDecl());
864fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor}
865fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
86639d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregorbool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
86739d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor  // FIXME: Visit the "outer" template parameter lists on the TagDecl
86839d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor  // before visiting these template parameters.
86939d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor  if (VisitTemplateParameters(D->getTemplateParameters()))
87039d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor    return true;
87139d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor
87239d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor  return VisitCXXRecordDecl(D->getTemplatedDecl());
87339d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor}
87439d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor
87584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregorbool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
87684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor  if (VisitTemplateParameters(D->getTemplateParameters()))
87784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor    return true;
87884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor
87984b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
88084b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor      VisitTemplateArgumentLoc(D->getDefaultArgument()))
88184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor    return true;
88284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor
88384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor  return false;
88484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor}
88584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor
8861ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
8874bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor  if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
8884bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor    if (Visit(TSInfo->getTypeLoc()))
8894bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor      return true;
8904bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor
891f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
8921ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor       PEnd = ND->param_end();
8931ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor       P != PEnd; ++P) {
8941ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor    if (Visit(MakeCXCursor(*P, TU)))
8951ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor      return true;
8961ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  }
897f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
8981ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  if (ND->isThisDeclarationADefinition() &&
8991ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor      Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
9001ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor    return true;
901f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
9021ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return false;
9031ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor}
9041ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor
905d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremeneknamespace {
906d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  struct ContainerDeclsSort {
907d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    SourceManager &SM;
908d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
909d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    bool operator()(Decl *A, Decl *B) {
910d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      SourceLocation L_A = A->getLocStart();
911d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      SourceLocation L_B = B->getLocStart();
912d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      assert(L_A.isValid() && L_B.isValid());
913d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      return SM.isBeforeInTranslationUnit(L_A, L_B);
914d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    }
915d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  };
916d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek}
917d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek
918a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregorbool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
919d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // FIXME: Eventually convert back to just 'VisitDeclContext()'.  Essentially
920d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // an @implementation can lexically contain Decls that are not properly
921d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // nested in the AST.  When we identify such cases, we need to retrofit
922d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // this nesting here.
923d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  if (!DI_current)
924d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    return VisitDeclContext(D);
925d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek
926d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // Scan the Decls that immediately come after the container
927d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // in the current DeclContext.  If any fall within the
928d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // container's lexical region, stash them into a vector
929d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // for later processing.
9305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 24> DeclsInContainer;
931d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  SourceLocation EndLoc = D->getSourceRange().getEnd();
932a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  SourceManager &SM = AU->getSourceManager();
933d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  if (EndLoc.isValid()) {
934d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    DeclContext::decl_iterator next = *DI_current;
935d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    while (++next != DE_current) {
936d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      Decl *D_next = *next;
937d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      if (!D_next)
938d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek        break;
939d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      SourceLocation L = D_next->getLocStart();
940d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      if (!L.isValid())
941d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek        break;
942d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
943d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek        *DI_current = next;
944d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek        DeclsInContainer.push_back(D_next);
945d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek        continue;
946d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      }
947d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      break;
948d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    }
949d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  }
950d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek
951d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // The common case.
952d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  if (DeclsInContainer.empty())
953d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    return VisitDeclContext(D);
954d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek
955d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // Get all the Decls in the DeclContext, and sort them with the
956d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // additional ones we've collected.  Then visit them.
957d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
958d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek       I!=E; ++I) {
959d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    Decl *subDecl = *I;
9600582c897ec7261b4c6af0fe26dc2a0b6b54d266cTed Kremenek    if (!subDecl || subDecl->getLexicalDeclContext() != D ||
9610582c897ec7261b4c6af0fe26dc2a0b6b54d266cTed Kremenek        subDecl->getLocStart().isInvalid())
962d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      continue;
963d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    DeclsInContainer.push_back(subDecl);
964d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  }
965d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek
966d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // Now sort the Decls so that they appear in lexical order.
967d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
968d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek            ContainerDeclsSort(SM));
969d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek
970d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  // Now visit the decls.
9715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
972d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek         E = DeclsInContainer.end(); I != E; ++I) {
973d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    CXCursor Cursor = MakeCXCursor(*I, TU);
974d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
975d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    if (!V.hasValue())
976d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      continue;
977d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    if (!V.getValue())
978d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      return false;
979d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek    if (Visit(Cursor, true))
980d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek      return true;
981d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  }
982d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek  return false;
983a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor}
984a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor
985b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
986b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor  if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
987b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor                                   TU)))
988b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    return true;
989f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
99078db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor  ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
99178db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor  for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
99278db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor         E = ND->protocol_end(); I != E; ++I, ++PL)
993b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
994b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor      return true;
995f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
996a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor  return VisitObjCContainerDecl(ND);
997dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek}
998dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek
9991ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
10001ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
10011ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
10021ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor       E = PID->protocol_end(); I != E; ++I, ++PL)
10031ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
10041ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor      return true;
1005f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
10061ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return VisitObjCContainerDecl(PID);
10071ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor}
10081ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor
100923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenekbool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
101083cb94269015bf2770ade71e616c5322ea7e76e1Douglas Gregor  if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1011fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall    return true;
1012fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall
101323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  // FIXME: This implements a workaround with @property declarations also being
101423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  // installed in the DeclContext for the @interface.  Eventually this code
101523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  // should be removed.
101623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
101723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  if (!CDecl || !CDecl->IsClassExtension())
101823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek    return false;
101923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek
102023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  ObjCInterfaceDecl *ID = CDecl->getClassInterface();
102123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  if (!ID)
102223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek    return false;
102323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek
102423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  IdentifierInfo *PropertyId = PD->getIdentifier();
102523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  ObjCPropertyDecl *prevDecl =
102623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek    ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
102723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek
102823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  if (!prevDecl)
102923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek    return false;
103023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek
103123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  // Visit synthesized methods since they will be skipped when visiting
103223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  // the @interface.
103323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1034a054fb46b1fb596d1719b89d2d9a5be3c32a4b0dTed Kremenek    if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
103523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek      if (Visit(MakeCXCursor(MD, TU)))
103623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek        return true;
103723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek
103823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1039a054fb46b1fb596d1719b89d2d9a5be3c32a4b0dTed Kremenek    if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
104023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek      if (Visit(MakeCXCursor(MD, TU)))
104123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek        return true;
104223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek
104323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek  return false;
104423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek}
104523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek
1046b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1047dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek  // Issue callbacks for super class.
1048b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  if (D->getSuperClass() &&
1049b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1050f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek                                        D->getSuperClassLoc(),
1051b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor                                        TU)))
1052b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor    return true;
1053f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
105478db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor  ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
105578db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
105678db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor         E = D->protocol_end(); I != E; ++I, ++PL)
1057b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1058b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor      return true;
1059f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
1060a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor  return VisitObjCContainerDecl(D);
1061dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek}
1062dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek
10631ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
10641ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return VisitObjCContainerDecl(D);
10651ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor}
10661ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor
10671ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1068ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek  // 'ID' could be null when dealing with invalid code.
1069ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek  if (ObjCInterfaceDecl *ID = D->getClassInterface())
1070ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek    if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1071ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek      return true;
1072f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
10731ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return VisitObjCImplDecl(D);
10741ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor}
10751ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor
10761ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
10771ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor#if 0
10781ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  // Issue callbacks for super class.
10791ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  // FIXME: No source location information!
10801ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  if (D->getSuperClass() &&
10811ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1082f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek                                        D->getSuperClassLoc(),
10831ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor                                        TU)))
1084a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor    return true;
10851ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor#endif
1086f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
10871ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return VisitObjCImplDecl(D);
1088dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek}
1089dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek
10901ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
10911ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
10921ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
10931ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor                                                  E = D->protocol_end();
10941ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor       I != E; ++I, ++PL)
1095b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1096b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor      return true;
1097f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
1098f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  return false;
1099dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek}
1100dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek
11011ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
110295ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian  if (Visit(MakeCursorObjCClassRef(D->getForwardInterfaceDecl(),
110395ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian                                   D->getForwardDecl()->getLocation(), TU)))
11041ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor      return true;
11051ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor  return false;
1106dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek}
11075e4bc590b0ea010e38372d0b4a0aab578a746fe6Benjamin Kramer
1108a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregorbool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1109a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1110a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor    return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1111a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor
1112a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor  return false;
1113a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor}
1114a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor
11158f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenekbool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
11168f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek  return VisitDeclContext(D);
11178f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek}
11188f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek
11196931900f43cea558c6974075256c07728dbfecc6Douglas Gregorbool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1120c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  // Visit nested-name-specifier.
11210cfaf6a270ecd0f5c7e541a8047c87948317548bDouglas Gregor  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
11220cfaf6a270ecd0f5c7e541a8047c87948317548bDouglas Gregor    if (VisitNestedNameSpecifierLoc(QualifierLoc))
1123c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor      return true;
11246931900f43cea558c6974075256c07728dbfecc6Douglas Gregor
11256931900f43cea558c6974075256c07728dbfecc6Douglas Gregor  return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
11266931900f43cea558c6974075256c07728dbfecc6Douglas Gregor                                      D->getTargetNameLoc(), TU));
11276931900f43cea558c6974075256c07728dbfecc6Douglas Gregor}
11286931900f43cea558c6974075256c07728dbfecc6Douglas Gregor
11297e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1130c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  // Visit nested-name-specifier.
1131dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1132dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    if (VisitNestedNameSpecifierLoc(QualifierLoc))
1133c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor      return true;
1134dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
11357e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor
11361f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
11371f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    return true;
11381f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
11397e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor  return VisitDeclarationNameInfo(D->getNameInfo());
11407e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor}
11417e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor
11420a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregorbool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1143c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  // Visit nested-name-specifier.
1144db9924191092b4d426cc066637d81698211846aaDouglas Gregor  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1145db9924191092b4d426cc066637d81698211846aaDouglas Gregor    if (VisitNestedNameSpecifierLoc(QualifierLoc))
1146c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor      return true;
11470a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor
11480a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor  return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
11490a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor                                      D->getIdentLocation(), TU));
11500a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor}
11510a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor
11527e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1153c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  // Visit nested-name-specifier.
1154dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1155dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    if (VisitNestedNameSpecifierLoc(QualifierLoc))
1156c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor      return true;
1157dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
1158c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor
11597e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor  return VisitDeclarationNameInfo(D->getNameInfo());
11607e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor}
11617e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor
11627e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
11637e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor                                               UnresolvedUsingTypenameDecl *D) {
1164c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  // Visit nested-name-specifier.
1165dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1166dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    if (VisitNestedNameSpecifierLoc(QualifierLoc))
1167c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor      return true;
1168c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor
11697e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor  return false;
11707e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor}
11717e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor
117201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
117301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  switch (Name.getName().getNameKind()) {
117401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case clang::DeclarationName::Identifier:
117501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case clang::DeclarationName::CXXLiteralOperatorName:
117601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case clang::DeclarationName::CXXOperatorName:
117701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case clang::DeclarationName::CXXUsingDirective:
117801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    return false;
117901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
118001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case clang::DeclarationName::CXXConstructorName:
118101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case clang::DeclarationName::CXXDestructorName:
118201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case clang::DeclarationName::CXXConversionFunctionName:
118301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
118401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor      return Visit(TSInfo->getTypeLoc());
118501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    return false;
118601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
118701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case clang::DeclarationName::ObjCZeroArgSelector:
118801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case clang::DeclarationName::ObjCOneArgSelector:
118901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case clang::DeclarationName::ObjCMultiArgSelector:
119001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    // FIXME: Per-identifier location info?
119101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    return false;
119201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  }
119301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
119401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  return false;
119501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor}
119601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
1197c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregorbool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1198c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor                                             SourceRange Range) {
1199c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  // FIXME: This whole routine is a hack to work around the lack of proper
1200c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  // source information in nested-name-specifiers (PR5791). Since we do have
1201c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  // a beginning source location, we can visit the first component of the
1202c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  // nested-name-specifier, if it's a single-token component.
1203c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  if (!NNS)
1204c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    return false;
1205c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor
1206c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  // Get the first component in the nested-name-specifier.
1207c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1208c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    NNS = Prefix;
1209c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor
1210c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  switch (NNS->getKind()) {
1211c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  case NestedNameSpecifier::Namespace:
1212c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1213c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor                                        TU));
1214c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor
121514aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor  case NestedNameSpecifier::NamespaceAlias:
121614aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor    return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
121714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor                                        Range.getBegin(), TU));
121814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor
1219c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  case NestedNameSpecifier::TypeSpec: {
1220c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    // If the type has a form where we know that the beginning of the source
1221c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    // range matches up with a reference cursor. Visit the appropriate reference
1222c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    // cursor.
1223f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall    const Type *T = NNS->getAsType();
1224c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1225c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor      return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1226c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    if (const TagType *Tag = dyn_cast<TagType>(T))
1227c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor      return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1228c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    if (const TemplateSpecializationType *TST
1229c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor                                      = dyn_cast<TemplateSpecializationType>(T))
1230c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor      return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1231c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    break;
1232c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  }
1233c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor
1234c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  case NestedNameSpecifier::TypeSpecWithTemplate:
1235c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  case NestedNameSpecifier::Global:
1236c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  case NestedNameSpecifier::Identifier:
1237c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor    break;
1238c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  }
1239c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor
1240c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor  return false;
1241c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor}
1242c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor
1243dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregorbool
1244dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas GregorCursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
12455f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1246dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  for (; Qualifier; Qualifier = Qualifier.getPrefix())
1247dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    Qualifiers.push_back(Qualifier);
1248dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
1249dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  while (!Qualifiers.empty()) {
1250dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1251dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1252dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    switch (NNS->getKind()) {
1253dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    case NestedNameSpecifier::Namespace:
1254dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor      if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1255c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor                                       Q.getLocalBeginLoc(),
1256dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor                                       TU)))
1257dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor        return true;
1258dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
1259dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor      break;
1260dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
1261dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    case NestedNameSpecifier::NamespaceAlias:
1262dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor      if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1263c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor                                       Q.getLocalBeginLoc(),
1264dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor                                       TU)))
1265dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor        return true;
1266dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
1267dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor      break;
1268dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
1269dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    case NestedNameSpecifier::TypeSpec:
1270dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    case NestedNameSpecifier::TypeSpecWithTemplate:
1271dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor      if (Visit(Q.getTypeLoc()))
1272dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor        return true;
1273dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
1274dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor      break;
1275dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
1276dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    case NestedNameSpecifier::Global:
1277dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    case NestedNameSpecifier::Identifier:
1278dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor      break;
1279dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor    }
1280dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  }
1281dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
1282dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  return false;
1283dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor}
1284dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
1285fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateParameters(
1286fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor                                          const TemplateParameterList *Params) {
1287fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  if (!Params)
1288fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return false;
1289fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1290fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  for (TemplateParameterList::const_iterator P = Params->begin(),
1291fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor                                          PEnd = Params->end();
1292fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor       P != PEnd; ++P) {
1293fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    if (Visit(MakeCXCursor(*P, TU)))
1294fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor      return true;
1295fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  }
1296fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1297fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  return false;
1298fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor}
1299fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
13000b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregorbool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
13010b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  switch (Name.getKind()) {
13020b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  case TemplateName::Template:
13030b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
13040b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
13050b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  case TemplateName::OverloadedTemplate:
13061f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    // Visit the overloaded template set.
13071f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
13081f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      return true;
13091f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
13100b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    return false;
13110b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
13120b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  case TemplateName::DependentTemplate:
13130b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    // FIXME: Visit nested-name-specifier.
13140b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    return false;
13150b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
13160b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  case TemplateName::QualifiedTemplate:
13170b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    // FIXME: Visit nested-name-specifier.
13180b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    return Visit(MakeCursorTemplateRef(
13190b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor                                  Name.getAsQualifiedTemplateName()->getDecl(),
13200b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor                                       Loc, TU));
1321146060435c3efce95c95a092c7a1eb651cfb9ae0John McCall
1322146060435c3efce95c95a092c7a1eb651cfb9ae0John McCall  case TemplateName::SubstTemplateTemplateParm:
1323146060435c3efce95c95a092c7a1eb651cfb9ae0John McCall    return Visit(MakeCursorTemplateRef(
1324146060435c3efce95c95a092c7a1eb651cfb9ae0John McCall                         Name.getAsSubstTemplateTemplateParm()->getParameter(),
1325146060435c3efce95c95a092c7a1eb651cfb9ae0John McCall                                       Loc, TU));
13261aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor
13271aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor  case TemplateName::SubstTemplateTemplateParmPack:
13281aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor    return Visit(MakeCursorTemplateRef(
13291aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor                  Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
13301aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor                                       Loc, TU));
13310b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  }
13320b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
13330b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  return false;
13340b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor}
13350b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
1336fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1337fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  switch (TAL.getArgument().getKind()) {
1338fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case TemplateArgument::Null:
1339fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case TemplateArgument::Integral:
1340fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case TemplateArgument::Pack:
1341fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return false;
134287dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor
1343fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case TemplateArgument::Type:
1344fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1345fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor      return Visit(TSInfo->getTypeLoc());
1346fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return false;
1347fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1348fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case TemplateArgument::Declaration:
1349fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    if (Expr *E = TAL.getSourceDeclExpression())
1350fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor      return Visit(MakeCXCursor(E, StmtParent, TU));
1351fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return false;
1352fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1353fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case TemplateArgument::Expression:
1354fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    if (Expr *E = TAL.getSourceExpression())
1355fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor      return Visit(MakeCXCursor(E, StmtParent, TU));
1356fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return false;
1357fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1358fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case TemplateArgument::Template:
1359a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor  case TemplateArgument::TemplateExpansion:
1360b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor    if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1361b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor      return true;
1362b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor
1363a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor    return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
13640b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor                             TAL.getTemplateNameLoc());
1365fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  }
1366fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1367fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  return false;
1368fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor}
1369fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1370a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenekbool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1371a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek  return VisitDeclContext(D);
1372a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek}
1373a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek
137401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
137501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  return Visit(TL.getUnqualifiedLoc());
137601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor}
137701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor
1378f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1379a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTContext &Context = AU->getASTContext();
1380f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1381f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  // Some builtin types (such as Objective-C's "id", "sel", and
1382f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  // "Class") have associated declarations. Create cursors for those.
1383f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  QualType VisitType;
1384f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  switch (TL.getType()->getAs<BuiltinType>()->getKind()) {
13856b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::Void:
1386f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  case BuiltinType::Bool:
13876b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::Char_U:
13886b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::UChar:
1389f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  case BuiltinType::Char16:
1390f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  case BuiltinType::Char32:
13916b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::UShort:
13926b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::UInt:
13936b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::ULong:
13946b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::ULongLong:
13956b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::UInt128:
1396f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  case BuiltinType::Char_S:
13976b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::SChar:
13983f59c975aa5d047f7edd1b900b5e885c38af0ef7Chris Lattner  case BuiltinType::WChar_U:
13993f59c975aa5d047f7edd1b900b5e885c38af0ef7Chris Lattner  case BuiltinType::WChar_S:
14006b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::Short:
1401f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  case BuiltinType::Int:
1402f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  case BuiltinType::Long:
1403c4174cc4b9b657abb77d0825de473ea29cf48297Ted Kremenek  case BuiltinType::LongLong:
14046b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::Int128:
14056b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::Float:
14066b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::Double:
14076b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::LongDouble:
1408f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  case BuiltinType::NullPtr:
1409f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  case BuiltinType::Overload:
1410864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall  case BuiltinType::BoundMember:
14116b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::Dependent:
14121de4d4e8cb2e9c88809fea8092bc6e835a5473d2John McCall  case BuiltinType::UnknownAny:
1413f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    break;
14146b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek
1415f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  case BuiltinType::ObjCId:
1416f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    VisitType = Context.getObjCIdType();
1417f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    break;
14186b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek
14196b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek  case BuiltinType::ObjCClass:
14206b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek    VisitType = Context.getObjCClassType();
14216b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek    break;
14226b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek
1423f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  case BuiltinType::ObjCSel:
1424f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    VisitType = Context.getObjCSelType();
1425f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    break;
1426f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  }
1427f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1428f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  if (!VisitType.isNull()) {
1429f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1430f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek      return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1431f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor                                     TU));
1432f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  }
1433f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1434f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  return false;
1435f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1436f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
14377d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorbool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1438162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
14397d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor}
14407d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor
1441f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1442f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1443f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1444f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1445f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
14466f155de99c59af890817146ec8526bafb6560f1fArgyrios Kyrtzidis  if (TL.isDefinition())
14476f155de99c59af890817146ec8526bafb6560f1fArgyrios Kyrtzidis    return Visit(MakeCXCursor(TL.getDecl(), TU));
14486f155de99c59af890817146ec8526bafb6560f1fArgyrios Kyrtzidis
1449f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1450f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1451f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1452fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1453960d13dde337a59dacc9dc3936c26d4aa8478986Chandler Carruth  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1454fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor}
1455fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1456f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1457f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1458f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    return true;
1459f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1460c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  return false;
1461c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall}
1462c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
1463c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallbool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1464c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1465c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall    return true;
1466c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
1467f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1468f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1469f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor                                        TU)))
1470f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor      return true;
1471f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  }
1472f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1473f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  return false;
1474f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1475f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1476f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1477c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  return Visit(TL.getPointeeLoc());
1478f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1479f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1480075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnarabool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1481075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara  return Visit(TL.getInnerLoc());
1482075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara}
1483075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara
1484f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1485f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  return Visit(TL.getPointeeLoc());
1486f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1487f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1488f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1489f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  return Visit(TL.getPointeeLoc());
1490f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1491f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1492f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1493f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  return Visit(TL.getPointeeLoc());
1494f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1495f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1496f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1497f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  return Visit(TL.getPointeeLoc());
1498f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1499f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1500f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1501f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  return Visit(TL.getPointeeLoc());
1502f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1503f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
15043422fbc38f35d9e486879850c5bf0175bd2eee16Argyrios Kyrtzidisbool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
15053422fbc38f35d9e486879850c5bf0175bd2eee16Argyrios Kyrtzidis  return Visit(TL.getModifiedLoc());
15063422fbc38f35d9e486879850c5bf0175bd2eee16Argyrios Kyrtzidis}
15073422fbc38f35d9e486879850c5bf0175bd2eee16Argyrios Kyrtzidis
150801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
150901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor                                         bool SkipResultType) {
151001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  if (!SkipResultType && Visit(TL.getResultLoc()))
1511f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    return true;
1512f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1513f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
15145dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek    if (Decl *D = TL.getArg(I))
15155dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek      if (Visit(MakeCXCursor(D, TU)))
15165dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek        return true;
1517f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1518f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  return false;
1519f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1520f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1521f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1522f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  if (Visit(TL.getElementLoc()))
1523f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    return true;
1524f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1525f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  if (Expr *Size = TL.getSizeExpr())
1526f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor    return Visit(MakeCXCursor(Size, StmtParent, TU));
1527f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1528f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor  return false;
1529f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor}
1530f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor
1531fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1532fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor                                             TemplateSpecializationTypeLoc TL) {
15330b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  // Visit the template name.
15340b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
15350b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor                        TL.getTemplateNameLoc()))
15360b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    return true;
1537fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1538fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  // Visit the template arguments.
1539fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1540fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1541fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor      return true;
1542fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1543fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  return false;
1544fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor}
1545fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
15462332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregorbool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
15472332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor  return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
15482332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor}
15492332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor
15502332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregorbool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
15512332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor  if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1552ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt    return Visit(TSInfo->getTypeLoc());
1553ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
1554ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  return false;
1555ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt}
1556ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
1557ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Huntbool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1558ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
15592332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor    return Visit(TSInfo->getTypeLoc());
15602332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor
15612332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor  return false;
15622332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor}
15632332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor
15642494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregorbool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
15652494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
15662494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    return true;
15672494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor
15682494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor  return false;
15692494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor}
15702494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor
157194fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregorbool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
157294fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor                                    DependentTemplateSpecializationTypeLoc TL) {
157394fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor  // Visit the nested-name-specifier, if there is one.
157494fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor  if (TL.getQualifierLoc() &&
157594fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor      VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
157694fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor    return true;
157794fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor
157894fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor  // Visit the template arguments.
157994fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
158094fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor    if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
158194fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor      return true;
158294fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor
158394fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor  return false;
158494fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor}
158594fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor
15869e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregorbool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
15879e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
15889e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor    return true;
15899e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor
15909e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor  return Visit(TL.getNamedTypeLoc());
15919e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor}
15929e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor
15937536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregorbool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
15947536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor  return Visit(TL.getPatternLoc());
15957536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor}
15967536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor
1597427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidisbool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1598427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis  if (Expr *E = TL.getUnderlyingExpr())
1599427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis    return Visit(MakeCXCursor(E, StmtParent, TU));
1600427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis
1601427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis  return false;
1602427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis}
1603427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis
1604427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidisbool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1605427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1606427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis}
1607427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis
1608427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1609427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidisbool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1610427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis  return Visit##PARENT##Loc(TL); \
1611427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis}
1612427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis
1613427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(Complex, Type)
1614427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1615427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1616427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1617427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1618427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1619427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(Vector, Type)
1620427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1621427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1622427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1623427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(Record, TagType)
1624427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(Enum, TagType)
1625427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1626427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1627427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(Auto, Type)
1628427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis
16293064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenekbool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1630c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  // Visit the nested-name-specifier, if present.
1631c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1632c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor    if (VisitNestedNameSpecifierLoc(QualifierLoc))
1633c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor      return true;
1634c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor
16353064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek  if (D->isDefinition()) {
16363064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
16373064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek         E = D->bases_end(); I != E; ++I) {
16383064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek      if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
16393064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek        return true;
16403064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek    }
16413064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek  }
16423064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek
16433064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek  return VisitTagDecl(D);
16443064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek}
16453064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek
164609dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenekbool CursorVisitor::VisitAttributes(Decl *D) {
1647cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt  for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1648cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt       i != e; ++i)
1649cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    if (Visit(MakeCXCursor(*i, D, TU)))
165009dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek        return true;
165109dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek
165209dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek  return false;
165309dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek}
165409dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek
1655c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===//
1656c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek// Data-recursive visitor methods.
1657c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===//
1658c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
165928a719433411ef782b582946823bc648ddcc4533Ted Kremeneknamespace {
1660035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek#define DEF_JOB(NAME, DATA, KIND)\
1661035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekclass NAME : public VisitorJob {\
1662035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekpublic:\
1663035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
1664035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
1665f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  DATA *get() const { return static_cast<DATA*>(data[0]); }\
1666035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek};
1667035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek
1668035dc41b509fcc470ceb6764aa64837505a2ece3Ted KremenekDEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1669035dc41b509fcc470ceb6764aa64837505a2ece3Ted KremenekDEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1670e4979ccb5960608edce73f3b274eb7c2de15dac5Ted KremenekDEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1671035dc41b509fcc470ceb6764aa64837505a2ece3Ted KremenekDEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
167260608ec12d17168a3d1f415409a6a6eaf6d94508Ted KremenekDEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
167360608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek        ExplicitTemplateArgsVisitKind)
167494d96291cd041adc5731a2294828a9c20e450b74Douglas GregorDEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1675035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek#undef DEF_JOB
1676035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek
1677035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekclass DeclVisit : public VisitorJob {
1678035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekpublic:
1679035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
1680035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek    VisitorJob(parent, VisitorJob::DeclVisitKind,
1681035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek               d, isFirst ? (void*) 1 : (void*) 0) {}
1682035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  static bool classof(const VisitorJob *VJ) {
168382f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek    return VJ->getKind() == DeclVisitKind;
1684035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  }
1685f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  Decl *get() const { return static_cast<Decl*>(data[0]); }
1686f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  bool isFirst() const { return data[1] ? true : false; }
1687035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek};
1688035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekclass TypeLocVisit : public VisitorJob {
1689035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekpublic:
1690035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  TypeLocVisit(TypeLoc tl, CXCursor parent) :
1691035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek    VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1692035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek               tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1693035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek
1694035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  static bool classof(const VisitorJob *VJ) {
1695035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek    return VJ->getKind() == TypeLocVisitKind;
1696035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  }
1697035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek
169882f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek  TypeLoc get() const {
1699f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    QualType T = QualType::getFromOpaquePtr(data[0]);
1700f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    return TypeLoc(T, data[1]);
1701035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  }
1702035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek};
1703035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek
1704ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenekclass LabelRefVisit : public VisitorJob {
1705ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenekpublic:
1706ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1707ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner    : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1708dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin                 labelLoc.getPtrEncoding()) {}
1709ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek
1710ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek  static bool classof(const VisitorJob *VJ) {
1711ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek    return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1712ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek  }
1713ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
1714ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek  SourceLocation getLoc() const {
1715dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin    return SourceLocation::getFromPtrEncoding(data[1]); }
1716f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek};
1717f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor
1718f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregorclass NestedNameSpecifierLocVisit : public VisitorJob {
1719f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregorpublic:
1720f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor  NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1721f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor    : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1722f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor                 Qualifier.getNestedNameSpecifier(),
1723f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor                 Qualifier.getOpaqueData()) { }
1724f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor
1725f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor  static bool classof(const VisitorJob *VJ) {
1726f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor    return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1727f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor  }
1728f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor
1729f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor  NestedNameSpecifierLoc get() const {
1730f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor    return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
1731f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor                                  data[1]);
1732f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor  }
1733f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor};
1734f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor
1735f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenekclass DeclarationNameInfoVisit : public VisitorJob {
1736f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenekpublic:
1737f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
1738f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
1739f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  static bool classof(const VisitorJob *VJ) {
1740f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1741f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  }
1742f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  DeclarationNameInfo get() const {
1743f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    Stmt *S = static_cast<Stmt*>(data[0]);
1744f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    switch (S->getStmtClass()) {
1745f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    default:
1746f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek      llvm_unreachable("Unhandled Stmt");
1747f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    case Stmt::CXXDependentScopeMemberExprClass:
1748f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek      return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1749f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    case Stmt::DependentScopeDeclRefExprClass:
1750f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek      return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1751f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    }
1752f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  }
1753ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek};
1754cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekclass MemberRefVisit : public VisitorJob {
1755cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekpublic:
1756cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
1757cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1758dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin                 L.getPtrEncoding()) {}
1759cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  static bool classof(const VisitorJob *VJ) {
1760cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1761cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  }
1762cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  FieldDecl *get() const {
1763cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    return static_cast<FieldDecl*>(data[0]);
1764cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  }
1765cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  SourceLocation getLoc() const {
1766cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1767cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  }
1768cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek};
176928a719433411ef782b582946823bc648ddcc4533Ted Kremenekclass EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
177028a719433411ef782b582946823bc648ddcc4533Ted Kremenek  VisitorWorkList &WL;
177128a719433411ef782b582946823bc648ddcc4533Ted Kremenek  CXCursor Parent;
177228a719433411ef782b582946823bc648ddcc4533Ted Kremenekpublic:
177328a719433411ef782b582946823bc648ddcc4533Ted Kremenek  EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
177428a719433411ef782b582946823bc648ddcc4533Ted Kremenek    : WL(wl), Parent(parent) {}
177528a719433411ef782b582946823bc648ddcc4533Ted Kremenek
1776ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek  void VisitAddrLabelExpr(AddrLabelExpr *E);
177773d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek  void VisitBlockExpr(BlockExpr *B);
177828a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
1779083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenek  void VisitCompoundStmt(CompoundStmt *S);
178011b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek  void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
1781f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
178211b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek  void VisitCXXNewExpr(CXXNewExpr *E);
17836d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek  void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
178428a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
1785cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
178673d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek  void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
1787b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenek  void VisitCXXTypeidExpr(CXXTypeidExpr *E);
178855b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek  void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
17891e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenek  void VisitCXXUuidofExpr(CXXUuidofExpr *E);
1790e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek  void VisitDeclRefExpr(DeclRefExpr *D);
1791035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  void VisitDeclStmt(DeclStmt *S);
1792f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
1793cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  void VisitDesignatedInitExpr(DesignatedInitExpr *E);
179428a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitExplicitCastExpr(ExplicitCastExpr *E);
179528a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitForStmt(ForStmt *FS);
1796ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek  void VisitGotoStmt(GotoStmt *GS);
179728a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitIfStmt(IfStmt *If);
179828a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitInitListExpr(InitListExpr *IE);
179928a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitMemberExpr(MemberExpr *M);
1800cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  void VisitOffsetOfExpr(OffsetOfExpr *E);
180173d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek  void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
180228a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitObjCMessageExpr(ObjCMessageExpr *M);
180328a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitOverloadExpr(OverloadExpr *E);
1804f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne  void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
180528a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitStmt(Stmt *S);
180628a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitSwitchStmt(SwitchStmt *S);
180728a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitWhileStmt(WhileStmt *W);
18082939b6f356161f572712d4d6310b65f9599e3675Ted Kremenek  void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
18096ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet  void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
181021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley  void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
1811552622067dc45013d240f73952fece703f5e63bdJohn Wiegley  void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
181228a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
18139d3bf79d94c961af95144ef63bbd6f9f3f32c59aTed Kremenek  void VisitVAArgExpr(VAArgExpr *E);
181494d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor  void VisitSizeOfPackExpr(SizeOfPackExpr *E);
1815ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor
181628a719433411ef782b582946823bc648ddcc4533Ted Kremenekprivate:
1817f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  void AddDeclarationNameInfo(Stmt *S);
1818f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor  void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
181960608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek  void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
1820cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  void AddMemberRef(FieldDecl *D, SourceLocation L);
182128a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void AddStmt(Stmt *S);
1822035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  void AddDecl(Decl *D, bool isFirst = true);
182328a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void AddTypeLoc(TypeSourceInfo *TI);
182428a719433411ef782b582946823bc648ddcc4533Ted Kremenek  void EnqueueChildren(Stmt *S);
182528a719433411ef782b582946823bc648ddcc4533Ted Kremenek};
182628a719433411ef782b582946823bc648ddcc4533Ted Kremenek} // end anonyous namespace
182728a719433411ef782b582946823bc648ddcc4533Ted Kremenek
1828f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenekvoid EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
1829f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  // 'S' should always be non-null, since it comes from the
1830f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  // statement we are visiting.
1831f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  WL.push_back(DeclarationNameInfoVisit(S, Parent));
1832f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek}
1833f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor
1834f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregorvoid
1835f3db29fff6a583ecda823cf909ab7737d8d30129Douglas GregorEnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1836f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor  if (Qualifier)
1837f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor    WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1838f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor}
1839f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor
184028a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::AddStmt(Stmt *S) {
184128a719433411ef782b582946823bc648ddcc4533Ted Kremenek  if (S)
184228a719433411ef782b582946823bc648ddcc4533Ted Kremenek    WL.push_back(StmtVisit(S, Parent));
184328a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
1844035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekvoid EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
184528a719433411ef782b582946823bc648ddcc4533Ted Kremenek  if (D)
1846035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek    WL.push_back(DeclVisit(D, Parent, isFirst));
184728a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
184860608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenekvoid EnqueueVisitor::
184960608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek  AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
185060608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek  if (A)
185160608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek    WL.push_back(ExplicitTemplateArgsVisit(
185260608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek                        const_cast<ExplicitTemplateArgumentList*>(A), Parent));
185360608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek}
1854cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekvoid EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
1855cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  if (D)
1856cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    WL.push_back(MemberRefVisit(D, L, Parent));
1857cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek}
185828a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
185928a719433411ef782b582946823bc648ddcc4533Ted Kremenek  if (TI)
186028a719433411ef782b582946823bc648ddcc4533Ted Kremenek    WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
186128a719433411ef782b582946823bc648ddcc4533Ted Kremenek }
186228a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::EnqueueChildren(Stmt *S) {
1863a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek  unsigned size = WL.size();
18647502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  for (Stmt::child_range Child = S->children(); Child; ++Child) {
186528a719433411ef782b582946823bc648ddcc4533Ted Kremenek    AddStmt(*Child);
1866a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek  }
1867a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek  if (size == WL.size())
1868a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek    return;
1869a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek  // Now reverse the entries we just added.  This will match the DFS
1870a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek  // ordering performed by the worklist.
1871a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1872a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek  std::reverse(I, E);
1873a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek}
1874ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenekvoid EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
1875ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek  WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1876ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek}
187773d15c452e675b684b7eee4f2096e386e59397aaTed Kremenekvoid EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
187873d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek  AddDecl(B->getBlockDecl());
187973d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek}
188028a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
188128a719433411ef782b582946823bc648ddcc4533Ted Kremenek  EnqueueChildren(E);
188228a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddTypeLoc(E->getTypeSourceInfo());
188328a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
1884083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenekvoid EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
1885083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenek  for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
1886083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenek        E = S->body_rend(); I != E; ++I) {
1887083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenek    AddStmt(*I);
1888083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenek  }
188911b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek}
1890f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenekvoid EnqueueVisitor::
1891f64d80306144f978148ba92f36f7cea7b671dd34Ted KremenekVisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
1892f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1893f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  AddDeclarationNameInfo(E);
18947c3179cf463c3b3b8c21dbb955f933ba50b74f28Douglas Gregor  if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
18957c3179cf463c3b3b8c21dbb955f933ba50b74f28Douglas Gregor    AddNestedNameSpecifierLoc(QualifierLoc);
1896f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  if (!E->isImplicitAccess())
1897f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek    AddStmt(E->getBase());
1898f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek}
189911b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenekvoid EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
190011b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek  // Enqueue the initializer or constructor arguments.
190111b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek  for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
190211b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek    AddStmt(E->getConstructorArg(I-1));
190311b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek  // Enqueue the array size, if any.
190411b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek  AddStmt(E->getArraySize());
190511b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek  // Enqueue the allocated type.
190611b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek  AddTypeLoc(E->getAllocatedTypeSourceInfo());
190711b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek  // Enqueue the placement arguments.
190811b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek  for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
190911b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek    AddStmt(E->getPlacementArg(I-1));
191011b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek}
191128a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
19128b8d8c90f2d8ac651d14b57f116d20b3c911ac7fTed Kremenek  for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
19138b8d8c90f2d8ac651d14b57f116d20b3c911ac7fTed Kremenek    AddStmt(CE->getArg(I-1));
191428a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(CE->getCallee());
191528a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(CE->getArg(0));
191628a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
1917cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekvoid EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1918cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  // Visit the name of the type being destroyed.
1919cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  AddTypeLoc(E->getDestroyedTypeInfo());
1920cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  // Visit the scope type that looks disturbingly like the nested-name-specifier
1921cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  // but isn't.
1922cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  AddTypeLoc(E->getScopeTypeInfo());
1923cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  // Visit the nested-name-specifier.
1924f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor  if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1925f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor    AddNestedNameSpecifierLoc(QualifierLoc);
1926cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  // Visit base expression.
1927cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  AddStmt(E->getBase());
1928cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek}
19296d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenekvoid EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
19306d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek  AddTypeLoc(E->getTypeSourceInfo());
19316d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek}
193273d15c452e675b684b7eee4f2096e386e59397aaTed Kremenekvoid EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
193373d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek  EnqueueChildren(E);
193473d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek  AddTypeLoc(E->getTypeSourceInfo());
193573d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek}
1936b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenekvoid EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1937b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenek  EnqueueChildren(E);
1938b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenek  if (E->isTypeOperand())
1939b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenek    AddTypeLoc(E->getTypeOperandSourceInfo());
1940b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenek}
194155b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek
194255b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenekvoid EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
194355b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek                                                     *E) {
194455b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek  EnqueueChildren(E);
194555b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek  AddTypeLoc(E->getTypeSourceInfo());
194655b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek}
19471e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenekvoid EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
19481e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenek  EnqueueChildren(E);
19491e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenek  if (E->isTypeOperand())
19501e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenek    AddTypeLoc(E->getTypeOperandSourceInfo());
19511e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenek}
1952e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenekvoid EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
195360608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek  if (DR->hasExplicitTemplateArgs()) {
195460608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek    AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
195560608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek  }
1956e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek  WL.push_back(DeclRefExprParts(DR, Parent));
1957e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek}
1958f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenekvoid EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1959f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1960f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek  AddDeclarationNameInfo(E);
196100cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor  AddNestedNameSpecifierLoc(E->getQualifierLoc());
1962f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek}
1963035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekvoid EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
1964035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  unsigned size = WL.size();
1965035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  bool isFirst = true;
1966035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
1967035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek       D != DEnd; ++D) {
1968035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek    AddDecl(*D, isFirst);
1969035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek    isFirst = false;
1970035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  }
1971035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  if (size == WL.size())
1972035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek    return;
1973035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  // Now reverse the entries we just added.  This will match the DFS
1974035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  // ordering performed by the worklist.
1975035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1976035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek  std::reverse(I, E);
1977035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek}
1978cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekvoid EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1979cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  AddStmt(E->getInit());
1980cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  typedef DesignatedInitExpr::Designator Designator;
1981cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  for (DesignatedInitExpr::reverse_designators_iterator
1982cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek         D = E->designators_rbegin(), DEnd = E->designators_rend();
1983cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek         D != DEnd; ++D) {
1984cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    if (D->isFieldDesignator()) {
1985cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek      if (FieldDecl *Field = D->getField())
1986cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek        AddMemberRef(Field, D->getFieldLoc());
1987cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek      continue;
1988cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    }
1989cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    if (D->isArrayDesignator()) {
1990cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek      AddStmt(E->getArrayIndex(*D));
1991cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek      continue;
1992cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    }
1993cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    assert(D->isArrayRangeDesignator() && "Unknown designator kind");
1994cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    AddStmt(E->getArrayRangeEnd(*D));
1995cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    AddStmt(E->getArrayRangeStart(*D));
1996cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  }
1997cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek}
199828a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
199928a719433411ef782b582946823bc648ddcc4533Ted Kremenek  EnqueueChildren(E);
200028a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddTypeLoc(E->getTypeInfoAsWritten());
200128a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
200228a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitForStmt(ForStmt *FS) {
200328a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(FS->getBody());
200428a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(FS->getInc());
200528a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(FS->getCond());
200628a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddDecl(FS->getConditionVariable());
200728a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(FS->getInit());
200828a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
2009ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenekvoid EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
2010ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek  WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2011ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek}
201228a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitIfStmt(IfStmt *If) {
201328a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(If->getElse());
201428a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(If->getThen());
201528a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(If->getCond());
201628a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddDecl(If->getConditionVariable());
201728a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
201828a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
201928a719433411ef782b582946823bc648ddcc4533Ted Kremenek  // We care about the syntactic form of the initializer list, only.
202028a719433411ef782b582946823bc648ddcc4533Ted Kremenek  if (InitListExpr *Syntactic = IE->getSyntacticForm())
202128a719433411ef782b582946823bc648ddcc4533Ted Kremenek    IE = Syntactic;
202228a719433411ef782b582946823bc648ddcc4533Ted Kremenek  EnqueueChildren(IE);
202328a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
202428a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
202589629a746019a42797495b091711a1d68467e88aDouglas Gregor  WL.push_back(MemberExprParts(M, Parent));
202689629a746019a42797495b091711a1d68467e88aDouglas Gregor
202789629a746019a42797495b091711a1d68467e88aDouglas Gregor  // If the base of the member access expression is an implicit 'this', don't
202889629a746019a42797495b091711a1d68467e88aDouglas Gregor  // visit it.
202989629a746019a42797495b091711a1d68467e88aDouglas Gregor  // FIXME: If we ever want to show these implicit accesses, this will be
203089629a746019a42797495b091711a1d68467e88aDouglas Gregor  // unfortunate. However, clang_getCursor() relies on this behavior.
203175e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor  if (!M->isImplicitAccess())
203275e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor    AddStmt(M->getBase());
203328a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
203473d15c452e675b684b7eee4f2096e386e59397aaTed Kremenekvoid EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
203573d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek  AddTypeLoc(E->getEncodedTypeSourceInfo());
203673d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek}
203728a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
203828a719433411ef782b582946823bc648ddcc4533Ted Kremenek  EnqueueChildren(M);
203928a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddTypeLoc(M->getClassReceiverTypeInfo());
204028a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
2041cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekvoid EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
2042cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  // Visit the components of the offsetof expression.
2043cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2044cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2045cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    const OffsetOfNode &Node = E->getComponent(I-1);
2046cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    switch (Node.getKind()) {
2047cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    case OffsetOfNode::Array:
2048cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek      AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2049cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek      break;
2050cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    case OffsetOfNode::Field:
205106dec892b5300b43263d25c5476b506c9d6cfbadAbramo Bagnara      AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2052cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek      break;
2053cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    case OffsetOfNode::Identifier:
2054cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    case OffsetOfNode::Base:
2055cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek      continue;
2056cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek    }
2057cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  }
2058cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  // Visit the type into which we're computing the offset.
2059cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek  AddTypeLoc(E->getTypeSourceInfo());
2060cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek}
206128a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
206260608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek  AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
20636045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek  WL.push_back(OverloadExprParts(E, Parent));
20646045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek}
2065f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbournevoid EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2066f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne                                              UnaryExprOrTypeTraitExpr *E) {
20676d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek  EnqueueChildren(E);
20686d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek  if (E->isArgumentType())
20696d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek    AddTypeLoc(E->getArgumentTypeInfo());
20706d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek}
207128a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitStmt(Stmt *S) {
207228a719433411ef782b582946823bc648ddcc4533Ted Kremenek  EnqueueChildren(S);
207328a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
207428a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
207528a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(S->getBody());
207628a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(S->getCond());
207728a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddDecl(S->getConditionVariable());
207828a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
2079fafa75aebadef8d6b44a920e3f40529f150a5574Ted Kremenek
208028a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
208128a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(W->getBody());
208228a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddStmt(W->getCond());
208328a719433411ef782b582946823bc648ddcc4533Ted Kremenek  AddDecl(W->getConditionVariable());
208428a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
208521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley
20862939b6f356161f572712d4d6310b65f9599e3675Ted Kremenekvoid EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
20872939b6f356161f572712d4d6310b65f9599e3675Ted Kremenek  AddTypeLoc(E->getQueriedTypeSourceInfo());
20882939b6f356161f572712d4d6310b65f9599e3675Ted Kremenek}
20896ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet
20906ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichetvoid EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
20916ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet  AddTypeLoc(E->getRhsTypeSourceInfo());
20920a03a3f98b14006a54bcac9e8908a7c9f50e519fFrancois Pichet  AddTypeLoc(E->getLhsTypeSourceInfo());
20936ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet}
20946ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet
209521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegleyvoid EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
209621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley  AddTypeLoc(E->getQueriedTypeSourceInfo());
209721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley}
209821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley
2099552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2100552622067dc45013d240f73952fece703f5e63bdJohn Wiegley  EnqueueChildren(E);
2101552622067dc45013d240f73952fece703f5e63bdJohn Wiegley}
2102552622067dc45013d240f73952fece703f5e63bdJohn Wiegley
210328a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
210428a719433411ef782b582946823bc648ddcc4533Ted Kremenek  VisitOverloadExpr(U);
210528a719433411ef782b582946823bc648ddcc4533Ted Kremenek  if (!U->isImplicitAccess())
210628a719433411ef782b582946823bc648ddcc4533Ted Kremenek    AddStmt(U->getBase());
210728a719433411ef782b582946823bc648ddcc4533Ted Kremenek}
21089d3bf79d94c961af95144ef63bbd6f9f3f32c59aTed Kremenekvoid EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
21099d3bf79d94c961af95144ef63bbd6f9f3f32c59aTed Kremenek  AddStmt(E->getSubExpr());
21109d3bf79d94c961af95144ef63bbd6f9f3f32c59aTed Kremenek  AddTypeLoc(E->getWrittenTypeInfo());
21119d3bf79d94c961af95144ef63bbd6f9f3f32c59aTed Kremenek}
211294d96291cd041adc5731a2294828a9c20e450b74Douglas Gregorvoid EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
211394d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor  WL.push_back(SizeOfPackExprParts(E, Parent));
211494d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor}
21156045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek
2116c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekvoid CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
211728a719433411ef782b582946823bc648ddcc4533Ted Kremenek  EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
2118c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek}
2119c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
2120c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekbool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2121c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  if (RegionOfInterest.isValid()) {
2122c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek    SourceRange Range = getRawCursorExtent(C);
2123c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek    if (Range.isInvalid() || CompareRegionOfInterest(Range))
2124c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek      return false;
2125c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  }
2126c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  return true;
2127c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek}
2128c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
2129c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekbool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2130c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  while (!WL.empty()) {
2131c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek    // Dequeue the worklist item.
213282f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek    VisitorJob LI = WL.back();
213382f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek    WL.pop_back();
213482f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek
2135c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek    // Set the Parent field, then back to its old value once we're done.
2136c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek    SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2137c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
2138c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek    switch (LI.getKind()) {
2139f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek      case VisitorJob::DeclVisitKind: {
214082f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek        Decl *D = cast<DeclVisit>(&LI)->get();
2141f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek        if (!D)
2142f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek          continue;
2143f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek
2144f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek        // For now, perform default visitation for Decls.
214582f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek        if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
2146f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek            return true;
2147f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek
2148f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek        continue;
2149f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek      }
215060608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek      case VisitorJob::ExplicitTemplateArgsVisitKind: {
215160608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek        const ExplicitTemplateArgumentList *ArgList =
215260608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek          cast<ExplicitTemplateArgsVisit>(&LI)->get();
215360608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek        for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
215460608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek               *ArgEnd = Arg + ArgList->NumTemplateArgs;
215560608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek               Arg != ArgEnd; ++Arg) {
215660608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek          if (VisitTemplateArgumentLoc(*Arg))
215760608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek            return true;
215860608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek        }
215960608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek        continue;
216060608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek      }
2161cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek      case VisitorJob::TypeLocVisitKind: {
2162cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek        // Perform default visitation for TypeLocs.
216382f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek        if (Visit(cast<TypeLocVisit>(&LI)->get()))
2164cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek          return true;
2165cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek        continue;
2166cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek      }
2167ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek      case VisitorJob::LabelRefVisitKind: {
2168ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner        LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
2169e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek        if (LabelStmt *stmt = LS->getStmt()) {
2170e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek          if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2171e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek                                       TU))) {
2172e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek            return true;
2173e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek          }
2174e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek        }
2175ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek        continue;
2176ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek      }
217747695c8ad8424851f62e0d4a983b45b15daee1c5Ted Kremenek
2178f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor      case VisitorJob::NestedNameSpecifierLocVisitKind: {
2179f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor        NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2180f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor        if (VisitNestedNameSpecifierLoc(V->get()))
2181f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor          return true;
2182f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor        continue;
2183f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor      }
2184f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor
2185f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek      case VisitorJob::DeclarationNameInfoVisitKind: {
2186f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek        if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2187f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek                                     ->get()))
2188f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek          return true;
2189f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek        continue;
2190f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek      }
2191cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek      case VisitorJob::MemberRefVisitKind: {
2192cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek        MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2193cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek        if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2194cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek          return true;
2195cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek        continue;
2196cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek      }
2197c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek      case VisitorJob::StmtVisitKind: {
219882f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek        Stmt *S = cast<StmtVisit>(&LI)->get();
21998c269ac75569454a049385b1246140db5f2b6faaTed Kremenek        if (!S)
22008c269ac75569454a049385b1246140db5f2b6faaTed Kremenek          continue;
22018c269ac75569454a049385b1246140db5f2b6faaTed Kremenek
2202f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek        // Update the current cursor.
2203c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek        CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
2204cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek        if (!IsInRegionOfInterest(Cursor))
2205cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek          continue;
2206cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek        switch (Visitor(Cursor, Parent, ClientData)) {
2207cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek          case CXChildVisit_Break: return true;
2208cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek          case CXChildVisit_Continue: break;
2209cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek          case CXChildVisit_Recurse:
2210cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek            EnqueueWorkList(WL, S);
221182f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek            break;
2212c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek        }
221382f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek        continue;
2214c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek      }
2215c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek      case VisitorJob::MemberExprPartsKind: {
2216c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek        // Handle the other pieces in the MemberExpr besides the base.
221782f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek        MemberExpr *M = cast<MemberExprParts>(&LI)->get();
2218c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
2219c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek        // Visit the nested-name-specifier
222040d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor        if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
222140d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor          if (VisitNestedNameSpecifierLoc(QualifierLoc))
2222c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek            return true;
2223c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
2224c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek        // Visit the declaration name.
2225c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek        if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2226c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek          return true;
2227c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
2228c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek        // Visit the explicitly-specified template arguments, if any.
2229c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek        if (M->hasExplicitTemplateArgs()) {
2230c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek          for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2231c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek               *ArgEnd = Arg + M->getNumTemplateArgs();
2232c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek               Arg != ArgEnd; ++Arg) {
2233c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek            if (VisitTemplateArgumentLoc(*Arg))
2234c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek              return true;
2235c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek          }
2236c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek        }
2237c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek        continue;
2238c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek      }
2239e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek      case VisitorJob::DeclRefExprPartsKind: {
224082f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek        DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
2241e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek        // Visit nested-name-specifier, if present.
224240d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor        if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
224340d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor          if (VisitNestedNameSpecifierLoc(QualifierLoc))
2244e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek            return true;
2245e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek        // Visit declaration name.
2246e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek        if (VisitDeclarationNameInfo(DR->getNameInfo()))
2247e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek          return true;
2248e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek        continue;
2249e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek      }
22506045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek      case VisitorJob::OverloadExprPartsKind: {
225182f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek        OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
22526045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek        // Visit the nested-name-specifier.
22534c9be89bb615ec07eb3ed507c8fa9d0baa8a5ad7Douglas Gregor        if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
22544c9be89bb615ec07eb3ed507c8fa9d0baa8a5ad7Douglas Gregor          if (VisitNestedNameSpecifierLoc(QualifierLoc))
22556045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek            return true;
22566045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek        // Visit the declaration name.
22576045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek        if (VisitDeclarationNameInfo(O->getNameInfo()))
22586045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek          return true;
22596045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek        // Visit the overloaded declaration reference.
22606045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek        if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
22616045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek          return true;
22626045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek        continue;
22636045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek      }
226494d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor      case VisitorJob::SizeOfPackExprPartsKind: {
226594d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor        SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
226694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor        NamedDecl *Pack = E->getPack();
226794d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor        if (isa<TemplateTypeParmDecl>(Pack)) {
226894d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor          if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
226994d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor                                      E->getPackLoc(), TU)))
227094d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor            return true;
227194d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor
227294d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor          continue;
227394d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor        }
227494d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor
227594d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor        if (isa<TemplateTemplateParmDecl>(Pack)) {
227694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor          if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
227794d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor                                          E->getPackLoc(), TU)))
227894d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor            return true;
227994d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor
228094d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor          continue;
228194d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor        }
228294d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor
228394d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor        // Non-type template parameter packs and function parameter packs are
228494d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor        // treated like DeclRefExpr cursors.
228594d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor        continue;
228694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor      }
2287c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek    }
2288c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  }
2289c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek  return false;
2290c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek}
2291c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
2292cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekbool CursorVisitor::Visit(Stmt *S) {
2293d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  VisitorWorkList *WL = 0;
2294d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  if (!WorkListFreeList.empty()) {
2295d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek    WL = WorkListFreeList.back();
2296d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek    WL->clear();
2297d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek    WorkListFreeList.pop_back();
2298d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  }
2299d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  else {
2300d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek    WL = new VisitorWorkList();
2301d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek    WorkListCache.push_back(WL);
2302d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  }
2303d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  EnqueueWorkList(*WL, S);
2304d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  bool result = RunVisitorWorkList(*WL);
2305d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  WorkListFreeList.push_back(WL);
2306d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek  return result;
2307c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek}
2308c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
230948a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichetnamespace {
231048a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichettypedef llvm::SmallVector<SourceRange, 4> RefNamePieces;
231148a8d14fc6f064a5297024c2b34733a4080b2efeFrancois PichetRefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
231248a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet                          const DeclarationNameInfo &NI,
231348a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet                          const SourceRange &QLoc,
231448a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet                          const ExplicitTemplateArgumentList *TemplateArgs = 0){
231548a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
231648a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
231748a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
231848a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet
231948a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  const DeclarationName::NameKind Kind = NI.getName().getNameKind();
232048a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet
232148a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  RefNamePieces Pieces;
232248a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet
232348a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  if (WantQualifier && QLoc.isValid())
232448a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet    Pieces.push_back(QLoc);
232548a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet
232648a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
232748a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet    Pieces.push_back(NI.getLoc());
232848a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet
232948a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  if (WantTemplateArgs && TemplateArgs)
233048a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet    Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
233148a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet                                 TemplateArgs->RAngleLoc));
233248a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet
233348a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  if (Kind == DeclarationName::CXXOperatorName) {
233448a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet    Pieces.push_back(SourceLocation::getFromRawEncoding(
233548a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet                       NI.getInfo().CXXOperatorName.BeginOpNameLoc));
233648a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet    Pieces.push_back(SourceLocation::getFromRawEncoding(
233748a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet                       NI.getInfo().CXXOperatorName.EndOpNameLoc));
233848a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  }
233948a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet
234048a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  if (WantSinglePiece) {
234148a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet    SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
234248a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet    Pieces.clear();
234348a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet    Pieces.push_back(R);
234448a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  }
234548a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet
234648a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet  return Pieces;
234748a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet}
234848a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet}
234948a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet
2350c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===//
2351c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek// Misc. API hooks.
2352c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===//
2353c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek
23548c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregorstatic llvm::sys::Mutex EnableMultithreadingMutex;
23558c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregorstatic bool EnabledMultithreading;
23568c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor
23575e4bc590b0ea010e38372d0b4a0aab578a746fe6Benjamin Kramerextern "C" {
23580a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas GregorCXIndex clang_createIndex(int excludeDeclarationsFromPCH,
23590a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor                          int displayDiagnostics) {
236048615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar  // Disable pretty stack trace functionality, which will otherwise be a very
236148615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar  // poor citizen of the world and set up all sorts of signal handlers.
236248615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar  llvm::DisablePrettyStackTrace = true;
236348615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar
2364c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar  // We use crash recovery to make some of our APIs more reliable, implicitly
2365c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar  // enable it.
2366c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar  llvm::CrashRecoveryContext::Enable();
2367c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar
23688c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor  // Enable support for multithreading in LLVM.
23698c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor  {
23708c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor    llvm::sys::ScopedLock L(EnableMultithreadingMutex);
23718c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor    if (!EnabledMultithreading) {
23728c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor      llvm::llvm_start_multithreaded();
23738c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor      EnabledMultithreading = true;
23748c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor    }
23758c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor  }
23768c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor
2377a030b7cf5e6aad5889b1b662b6979840bc75f87fDouglas Gregor  CIndexer *CIdxr = new CIndexer();
2378e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff  if (excludeDeclarationsFromPCH)
2379e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff    CIdxr->setOnlyLocalDecls();
23800a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  if (displayDiagnostics)
23810a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    CIdxr->setDisplayDiagnostics();
2382e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff  return CIdxr;
2383600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff}
2384600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff
23859ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarvoid clang_disposeIndex(CXIndex CIdx) {
23862b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor  if (CIdx)
23872b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor    delete static_cast<CIndexer *>(CIdx);
23882bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff}
23892bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff
2390d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenekvoid clang_toggleCrashRecovery(unsigned isEnabled) {
2391d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek  if (isEnabled)
2392d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek    llvm::CrashRecoveryContext::Enable();
2393d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek  else
2394d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek    llvm::CrashRecoveryContext::Disable();
2395d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek}
2396d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek
23979ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2398a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                              const char *ast_filename) {
23992b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor  if (!CIdx)
24002b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor    return 0;
2401f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
24027d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2403389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis  FileSystemOptions FileSystemOpts;
2404389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis  FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
24050d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar
240628019772db70d4547be05a042eb950bc910f134fDouglas Gregor  llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
2407a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2408a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                  CXXIdx->getOnlyLocalDecls(),
2409a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                  0, 0, true);
2410a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  return MakeCXTranslationUnit(TU);
2411600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff}
2412600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff
2413b1c031be513705d924038f497279b9b599868ba1Douglas Gregorunsigned clang_defaultEditingTranslationUnitOptions() {
24142a2c50b330e7754499f42173616a36865b5f313bDouglas Gregor  return CXTranslationUnit_PrecompiledPreamble |
2415b5af843a20e237ad1a13ad66a867e200695b8c8eDouglas Gregor         CXTranslationUnit_CacheCompletionResults;
2416b1c031be513705d924038f497279b9b599868ba1Douglas Gregor}
2417b1c031be513705d924038f497279b9b599868ba1Douglas Gregor
24189ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXTranslationUnit
24199ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarclang_createTranslationUnitFromSourceFile(CXIndex CIdx,
24209ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar                                          const char *source_filename,
24219ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar                                          int num_command_line_args,
24222ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor                                          const char * const *command_line_args,
24234db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor                                          unsigned num_unsaved_files,
2424a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                          struct CXUnsavedFile *unsaved_files) {
2425dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor  unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord |
2426ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth                     CXTranslationUnit_NestedMacroExpansions;
24275a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor  return clang_parseTranslationUnit(CIdx, source_filename,
24285a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor                                    command_line_args, num_command_line_args,
24295a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor                                    unsaved_files, num_unsaved_files,
2430dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor                                    Options);
24315a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor}
243219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar
243319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbarstruct ParseTranslationUnitInfo {
243419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  CXIndex CIdx;
243519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  const char *source_filename;
24362ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor  const char *const *command_line_args;
243719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  int num_command_line_args;
243819ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  struct CXUnsavedFile *unsaved_files;
243919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  unsigned num_unsaved_files;
244019ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  unsigned options;
244119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  CXTranslationUnit result;
244219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar};
2443b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarstatic void clang_parseTranslationUnit_Impl(void *UserData) {
244419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  ParseTranslationUnitInfo *PTUI =
244519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar    static_cast<ParseTranslationUnitInfo*>(UserData);
244619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  CXIndex CIdx = PTUI->CIdx;
244719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  const char *source_filename = PTUI->source_filename;
24482ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor  const char * const *command_line_args = PTUI->command_line_args;
244919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  int num_command_line_args = PTUI->num_command_line_args;
245019ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
245119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  unsigned num_unsaved_files = PTUI->num_unsaved_files;
245219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  unsigned options = PTUI->options;
245319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  PTUI->result = 0;
24545a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor
24552b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor  if (!CIdx)
245619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar    return;
2457f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
2458e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2459e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff
246044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2461467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor  // FIXME: Add a flag for modules.
2462467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor  TranslationUnitKind TUKind
2463467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor    = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
246487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor  bool CacheCodeCompetionResults
246587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor    = options & CXTranslationUnit_CacheCompletionResults;
246687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor
24675352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  // Configure the diagnostics.
24685352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  DiagnosticOptions DiagOpts;
246925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::IntrusiveRefCntPtr<Diagnostic>
247025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
247125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek                                                command_line_args));
247225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek
247325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  // Recover resources if we crash before exiting this function.
247425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
247525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
247625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    DiagCleanup(Diags.getPtr());
247725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek
247825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
247925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
248025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek
248125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  // Recover resources if we crash before exiting this function.
248225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<
248325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2484f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
24854db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  for (unsigned I = 0; I != num_unsaved_files; ++I) {
24865f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2487f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek    const llvm::MemoryBuffer *Buffer
2488a0a270c0f1c0a4e3482438bdc5f4a7bd3d25f0a6Chris Lattner      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
248925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
249025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek                                            Buffer));
24914db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  }
2492f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
249325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::OwningPtr<std::vector<const char *> >
249425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    Args(new std::vector<const char*>());
249525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek
249625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  // Recover resources if we crash before exiting this method.
249725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
249825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    ArgsCleanup(Args.get());
249925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek
250052ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor  // Since the Clang C library is primarily used by batch tools dealing with
250152ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor  // (often very broken) source code, where spell-checking can have a
250252ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor  // significant negative impact on performance (particularly when
250352ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor  // precompiled headers are involved), we disable it by default.
2504b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor  // Only do this if we haven't found a spell-checking-related argument.
2505b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor  bool FoundSpellCheckingArgument = false;
2506b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor  for (int I = 0; I != num_command_line_args; ++I) {
2507b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor    if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2508b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor        strcmp(command_line_args[I], "-fspell-checking") == 0) {
2509b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor      FoundSpellCheckingArgument = true;
2510b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor      break;
2511e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff    }
2512b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor  }
2513b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor  if (!FoundSpellCheckingArgument)
251425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    Args->push_back("-fno-spell-checking");
2515b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor
251625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  Args->insert(Args->end(), command_line_args,
251725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek               command_line_args + num_command_line_args);
2518d93256e55673a17d18543397ec462416acb13792Douglas Gregor
2519c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis  // The 'source_filename' argument is optional.  If the caller does not
2520c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis  // specify it then it is assumed that the source file is specified
2521c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis  // in the actual argument list.
2522c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis  // Put the source file after command_line_args otherwise if '-x' flag is
2523c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis  // present it will be unused.
2524c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis  if (source_filename)
252525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    Args->push_back(source_filename);
2526c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis
252744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  // Do we need the detailed preprocessing record?
2528ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth  bool NestedMacroExpansions = false;
252944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
253025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    Args->push_back("-Xclang");
253125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    Args->push_back("-detailed-preprocessing-record");
2532ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth    NestedMacroExpansions
2533ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth      = (options & CXTranslationUnit_NestedMacroExpansions);
253444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor  }
253544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor
2536026f6911bb985c800a54446de9f6da8745ae025aArgyrios Kyrtzidis  unsigned NumErrors = Diags->getClient()->getNumErrors();
2537b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor  llvm::OwningPtr<ASTUnit> Unit(
25384ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek    ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
25394ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek                                 /* vector::data() not portable */,
25404ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek                                 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2541b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor                                 Diags,
2542b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor                                 CXXIdx->getClangResourcesPath(),
2543b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor                                 CXXIdx->getOnlyLocalDecls(),
2544e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor                                 /*CaptureDiagnostics=*/true,
25454ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek                                 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
254625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek                                 RemappedFiles->size(),
2547299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis                                 /*RemappedFilesKeepOriginalName=*/true,
2548b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor                                 PrecompilePreamble,
2549467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor                                 TUKind,
255099ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor                                 CacheCodeCompetionResults,
2551ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth                                 NestedMacroExpansions));
2552b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor
2553026f6911bb985c800a54446de9f6da8745ae025aArgyrios Kyrtzidis  if (NumErrors != Diags->getClient()->getNumErrors()) {
2554b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor    // Make sure to check that 'Unit' is non-NULL.
2555b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor    if (CXXIdx->getDisplayDiagnostics() && Unit.get()) {
2556b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor      for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
2557b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor                                      DEnd = Unit->stored_diag_end();
2558b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor           D != DEnd; ++D) {
2559b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor        CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions());
2560b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor        CXString Msg = clang_formatDiagnostic(&Diag,
2561b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor                                    clang_defaultDiagnosticDisplayOptions());
2562b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor        fprintf(stderr, "%s\n", clang_getCString(Msg));
2563b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor        clang_disposeString(Msg);
2564b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor      }
2565274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor#ifdef LLVM_ON_WIN32
2566b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor      // On Windows, force a flush, since there may be multiple copies of
2567b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor      // stderr and stdout in the file system, all with different buffers
2568b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor      // but writing to the same device.
2569b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor      fflush(stderr);
2570b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor#endif
2571b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor    }
2572a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  }
2573d93256e55673a17d18543397ec462416acb13792Douglas Gregor
2574a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  PTUI->result = MakeCXTranslationUnit(Unit.take());
257519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar}
257619ffd492a31a25fb691098bf79f317e5f3edf177Daniel DunbarCXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
257719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar                                             const char *source_filename,
25782ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor                                         const char * const *command_line_args,
257919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar                                             int num_command_line_args,
25809e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar                                            struct CXUnsavedFile *unsaved_files,
258119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar                                             unsigned num_unsaved_files,
258219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar                                             unsigned options) {
258319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
25849e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar                                    num_command_line_args, unsaved_files,
25859e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar                                    num_unsaved_files, options, 0 };
258619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  llvm::CrashRecoveryContext CRC;
258719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar
2588bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar  if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
258960a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    fprintf(stderr, "libclang: crash detected during parsing: {\n");
259060a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
259160a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    fprintf(stderr, "  'command_line_args' : [");
259260a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    for (int i = 0; i != num_command_line_args; ++i) {
259360a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar      if (i)
259460a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar        fprintf(stderr, ", ");
259560a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar      fprintf(stderr, "'%s'", command_line_args[i]);
259660a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    }
259760a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    fprintf(stderr, "],\n");
259860a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    fprintf(stderr, "  'unsaved_files' : [");
259960a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    for (unsigned i = 0; i != num_unsaved_files; ++i) {
260060a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar      if (i)
260160a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar        fprintf(stderr, ", ");
260260a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar      fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
260360a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar              unsaved_files[i].Length);
260460a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    }
260560a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    fprintf(stderr, "],\n");
260660a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    fprintf(stderr, "  'options' : %d,\n", options);
260760a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar    fprintf(stderr, "}\n");
260860a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar
260919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar    return 0;
26106df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
26116df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor    PrintLibclangResourceUsage(PTUI.result);
261219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  }
26136df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor
261419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar  return PTUI.result;
26155b7d8e254f6c2855b37b5521c0aee0a560dab237Steve Naroff}
26165b7d8e254f6c2855b37b5521c0aee0a560dab237Steve Naroff
26171999844e7a18786e61e619e1dc6c789827541863Douglas Gregorunsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
26181999844e7a18786e61e619e1dc6c789827541863Douglas Gregor  return CXSaveTranslationUnit_None;
26191999844e7a18786e61e619e1dc6c789827541863Douglas Gregor}
26201999844e7a18786e61e619e1dc6c789827541863Douglas Gregor
26211999844e7a18786e61e619e1dc6c789827541863Douglas Gregorint clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
26221999844e7a18786e61e619e1dc6c789827541863Douglas Gregor                              unsigned options) {
26237ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor  if (!TU)
262439c411fa229b2a6747b92f945d1702ee674d3470Douglas Gregor    return CXSaveError_InvalidTU;
26257ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor
262639c411fa229b2a6747b92f945d1702ee674d3470Douglas Gregor  CXSaveError result = static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
26276df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor  if (getenv("LIBCLANG_RESOURCE_USAGE"))
26286df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor    PrintLibclangResourceUsage(TU);
26296df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor  return result;
26307ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor}
263119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar
26329ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarvoid clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2633ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  if (CTUnit) {
2634ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar    // If the translation unit has been marked as unsafe to free, just discard
2635ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar    // it.
2636a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
2637ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar      return;
2638ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar
2639a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    delete static_cast<ASTUnit *>(CTUnit->TUData);
2640a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    disposeCXStringPool(CTUnit->StringPool);
2641a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    delete CTUnit;
2642ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  }
26432bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff}
26440d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar
2645e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregorunsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2646e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor  return CXReparse_None;
2647e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor}
2648e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor
2649ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbarstruct ReparseTranslationUnitInfo {
2650ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  CXTranslationUnit TU;
2651ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  unsigned num_unsaved_files;
2652ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  struct CXUnsavedFile *unsaved_files;
2653ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  unsigned options;
2654ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  int result;
2655ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar};
2656593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor
2657b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarstatic void clang_reparseTranslationUnit_Impl(void *UserData) {
2658ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  ReparseTranslationUnitInfo *RTUI =
2659ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar    static_cast<ReparseTranslationUnitInfo*>(UserData);
2660ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  CXTranslationUnit TU = RTUI->TU;
2661ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  unsigned num_unsaved_files = RTUI->num_unsaved_files;
2662ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2663ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  unsigned options = RTUI->options;
2664ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  (void) options;
2665ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  RTUI->result = 1;
2666ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar
2667abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  if (!TU)
2668ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar    return;
2669593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor
2670a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
2671593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2672abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
267325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
267425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
267525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek
267625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  // Recover resources if we crash before exiting this function.
267725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek  llvm::CrashRecoveryContextCleanupRegistrar<
267825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
267925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek
2680abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  for (unsigned I = 0; I != num_unsaved_files; ++I) {
26815f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2682abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor    const llvm::MemoryBuffer *Buffer
26831abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
268425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek    RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
268525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek                                            Buffer));
2686abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor  }
2687abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor
26884ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek  if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
26894ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek                        RemappedFiles->size()))
2690593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor    RTUI->result = 0;
2691abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor}
2692593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor
2693ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbarint clang_reparseTranslationUnit(CXTranslationUnit TU,
2694ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar                                 unsigned num_unsaved_files,
2695ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar                                 struct CXUnsavedFile *unsaved_files,
2696ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar                                 unsigned options) {
2697ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2698ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar                                      options, 0 };
2699ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  llvm::CrashRecoveryContext CRC;
2700ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar
2701bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar  if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2702b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar    fprintf(stderr, "libclang: crash detected during reparsing\n");
2703a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
2704ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar    return 1;
27056df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor  } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
27066df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor    PrintLibclangResourceUsage(TU);
27071dfb26af4d6aa4f7818e256659a79f1ec2cba784Ted Kremenek
2708ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar  return RTUI.result;
2709ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar}
2710ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar
2711df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
27129ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
27132b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor  if (!CTUnit)
2714ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek    return createCXString("");
2715f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
2716a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
2717ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek  return createCXString(CXXUnit->getOriginalSourceFileName(), true);
2718af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff}
27191eb79b58e56b99cf557d5d353586a10c5360364dDaniel Dunbar
27207eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas GregorCXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
2721b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor  CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
27227eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor  return Result;
27237eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor}
27247eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor
2725fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C"
2726600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff
2727fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===//
27281db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor// CXSourceLocation and CXSourceRange Operations.
27291db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor//===----------------------------------------------------------------------===//
27301db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor
2731b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregorextern "C" {
2732b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceLocation clang_getNullLocation() {
27335352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  CXSourceLocation Result = { { 0, 0 }, 0 };
2734b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor  return Result;
2735b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor}
2736b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor
2737b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregorunsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
273890a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar  return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
273990a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar          loc1.ptr_data[1] == loc2.ptr_data[1] &&
274090a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar          loc1.int_data == loc2.int_data);
2741b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor}
2742b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor
2743b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceLocation clang_getLocation(CXTranslationUnit tu,
2744b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor                                   CXFile file,
2745b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor                                   unsigned line,
2746b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor                                   unsigned column) {
274742748ec5cb2d75fe0dbb3a6db5aee6c11b5dc190Douglas Gregor  if (!tu || !file)
2748b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor    return clang_getNullLocation();
274942748ec5cb2d75fe0dbb3a6db5aee6c11b5dc190Douglas Gregor
275086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor  bool Logging = ::getenv("LIBCLANG_LOGGING");
2751a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
275286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor  const FileEntry *File = static_cast<const FileEntry *>(file);
2753b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor  SourceLocation SLoc
275486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor    = CXXUnit->getSourceManager().getLocation(File, line, column);
275586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor  if (SLoc.isInvalid()) {
275686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor    if (Logging)
275786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor      llvm::errs() << "clang_getLocation(\"" << File->getName()
275886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor                   << "\", " << line << ", " << column << ") = invalid\n";
275986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor    return clang_getNullLocation();
276086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor  }
276186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor
276286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor  if (Logging)
276386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor    llvm::errs() << "clang_getLocation(\"" << File->getName()
276486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor                 << "\", " << line << ", " << column << ") = "
276586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor                 << SLoc.getRawEncoding() << "\n";
276683889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall
276783889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall  return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
276883889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall}
276983889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall
277083889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid ChisnallCXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
277183889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall                                            CXFile file,
277283889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall                                            unsigned offset) {
277383889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall  if (!tu || !file)
277483889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall    return clang_getNullLocation();
277583889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall
2776a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
277783889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall  SourceLocation Start
277883889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall    = CXXUnit->getSourceManager().getLocation(
277983889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall                                        static_cast<const FileEntry *>(file),
278083889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall                                              1, 1);
278183889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall  if (Start.isInvalid()) return clang_getNullLocation();
278283889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall
2783a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis  SourceLocation SLoc = Start.getLocWithOffset(offset);
278483889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall
278583889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall  if (SLoc.isInvalid()) return clang_getNullLocation();
2786f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
27871a9a0bc472ee4fec72ee8be8b575fb66ca600d1bTed Kremenek  return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
2788b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor}
2789b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor
27905352ac06d8f6194825bb2a99ffa009b61bafb503Douglas GregorCXSourceRange clang_getNullRange() {
27915352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  CXSourceRange Result = { { 0, 0 }, 0, 0 };
27925352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  return Result;
27935352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
2794d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar
2795b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
27965352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  if (begin.ptr_data[0] != end.ptr_data[0] ||
27975352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor      begin.ptr_data[1] != end.ptr_data[1])
27985352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor    return clang_getNullRange();
2799f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
2800f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
28015352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor                           begin.int_data, end.int_data };
2802b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor  return Result;
2803b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor}
2804ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor
2805ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregorunsigned clang_equalRanges(CXSourceRange range1, CXSourceRange range2)
2806ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor{
2807ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor  return range1.ptr_data[0] == range2.ptr_data[0]
2808ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor      && range1.ptr_data[1] == range2.ptr_data[1]
2809ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor      && range1.begin_int_data == range2.begin_int_data
2810ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor      && range1.end_int_data == range2.end_int_data;
2811ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor}
28129d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek} // end: extern "C"
2813b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor
28149d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenekstatic void createNullLocation(CXFile *file, unsigned *line,
28159d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek                               unsigned *column, unsigned *offset) {
28169d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek  if (file)
28179d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek   *file = 0;
28189d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek  if (line)
28199d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek   *line = 0;
28209d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek  if (column)
28219d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek   *column = 0;
28229d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek  if (offset)
28239d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek   *offset = 0;
28249d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek  return;
28259d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek}
28269d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek
28279d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenekextern "C" {
282820174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruthvoid clang_getExpansionLocation(CXSourceLocation location,
282920174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth                                CXFile *file,
283020174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth                                unsigned *line,
283120174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth                                unsigned *column,
283220174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth                                unsigned *offset) {
28331db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
28341db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor
2835bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar  if (!location.ptr_data[0] || Loc.isInvalid()) {
28369d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek    createNullLocation(file, line, column, offset);
283746766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor    return;
283846766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor  }
283946766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor
2840bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar  const SourceManager &SM =
2841bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar    *static_cast<const SourceManager*>(location.ptr_data[0]);
284220174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth  SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
28431db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor
2844cea731a9cb7de3f473d60e5ea544e25621cebd76Chandler Carruth  // Check that the FileID is invalid on the expansion location.
28459d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek  // This can manifest in invalid code.
284620174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth  FileID fileID = SM.getFileID(ExpansionLoc);
2847e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor  bool Invalid = false;
2848e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor  const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
2849e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor  if (!sloc.isFile() || Invalid) {
28509d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek    createNullLocation(file, line, column, offset);
28519d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek    return;
28529d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek  }
28539d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek
28541db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor  if (file)
28559d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek    *file = (void *)SM.getFileEntryForSLocEntry(sloc);
28561db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor  if (line)
285720174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth    *line = SM.getExpansionLineNumber(ExpansionLoc);
28581db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor  if (column)
285920174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth    *column = SM.getExpansionColumnNumber(ExpansionLoc);
2860e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor  if (offset)
286120174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth    *offset = SM.getDecomposedLoc(ExpansionLoc).second;
286220174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth}
286320174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth
2864e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidisvoid clang_getPresumedLocation(CXSourceLocation location,
2865e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis                               CXString *filename,
2866e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis                               unsigned *line,
2867e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis                               unsigned *column) {
2868e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2869e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis
2870e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis  if (!location.ptr_data[0] || Loc.isInvalid()) {
2871e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis    if (filename)
2872e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis      *filename = createCXString("");
2873e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis    if (line)
2874e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis      *line = 0;
2875e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis    if (column)
2876e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis      *column = 0;
2877e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis  }
2878e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis  else {
2879e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis	const SourceManager &SM =
2880e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis        *static_cast<const SourceManager*>(location.ptr_data[0]);
2881e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis    PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
2882e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis
2883e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis    if (filename)
2884e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis      *filename = createCXString(PreLoc.getFilename());
2885e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis    if (line)
2886e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis      *line = PreLoc.getLine();
2887e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis    if (column)
2888e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis      *column = PreLoc.getColumn();
2889e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis  }
2890e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis}
2891e6be34d8f77312edf9ed38034e52cb4d22c8e1c1Argyrios Kyrtzidis
289220174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruthvoid clang_getInstantiationLocation(CXSourceLocation location,
289320174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth                                    CXFile *file,
289420174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth                                    unsigned *line,
289520174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth                                    unsigned *column,
289620174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth                                    unsigned *offset) {
289720174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth  // Redirect to new API.
289820174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth  clang_getExpansionLocation(location, file, line, column, offset);
2899e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor}
2900e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor
2901a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregorvoid clang_getSpellingLocation(CXSourceLocation location,
2902a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                               CXFile *file,
2903a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                               unsigned *line,
2904a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                               unsigned *column,
2905a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                               unsigned *offset) {
2906a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
2907a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor
29085adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis  if (!location.ptr_data[0] || Loc.isInvalid())
29095adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis    return createNullLocation(file, line, column, offset);
2910a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor
2911a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  const SourceManager &SM =
2912a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    *static_cast<const SourceManager*>(location.ptr_data[0]);
2913a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  SourceLocation SpellLoc = Loc;
2914a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  if (SpellLoc.isMacroID()) {
2915a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
2916a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    if (SimpleSpellingLoc.isFileID() &&
2917a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor        SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
2918a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor      SpellLoc = SimpleSpellingLoc;
2919a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    else
2920402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth      SpellLoc = SM.getExpansionLoc(SpellLoc);
2921a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  }
2922a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor
2923a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
2924a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  FileID FID = LocInfo.first;
2925a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  unsigned FileOffset = LocInfo.second;
2926a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor
29275adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis  if (FID.isInvalid())
29285adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis    return createNullLocation(file, line, column, offset);
29295adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis
2930a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  if (file)
2931a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    *file = (void *)SM.getFileEntryForID(FID);
2932a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  if (line)
2933a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    *line = SM.getLineNumber(FID, FileOffset);
2934a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  if (column)
2935a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    *column = SM.getColumnNumber(FID, FileOffset);
2936a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor  if (offset)
2937a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    *offset = FileOffset;
2938a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor}
2939a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor
29401db19dea8d221f27be46332d668d1e2decb7f1abDouglas GregorCXSourceLocation clang_getRangeStart(CXSourceRange range) {
2941f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
29425352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor                              range.begin_int_data };
29431db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor  return Result;
29441db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor}
29451db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor
29461db19dea8d221f27be46332d668d1e2decb7f1abDouglas GregorCXSourceLocation clang_getRangeEnd(CXSourceRange range) {
2947bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar  CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
29485352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor                              range.end_int_data };
29491db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor  return Result;
29501db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor}
29511db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor
2952b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} // end: extern "C"
2953b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor
29541db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor//===----------------------------------------------------------------------===//
2955fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek// CXFile Operations.
2956fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===//
2957fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek
2958fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekextern "C" {
295974844072411bae91d5dbb89955d200cbe1e0a1c8Ted KremenekCXString clang_getFileName(CXFile SFile) {
296098258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor  if (!SFile)
2961a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    return createCXString((const char*)NULL);
2962f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
296388145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
296474844072411bae91d5dbb89955d200cbe1e0a1c8Ted Kremenek  return createCXString(FEnt->getName());
296588145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff}
296688145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff
296788145034694ed5267fa6fa5febc54fadc02bd479Steve Narofftime_t clang_getFileTime(CXFile SFile) {
296898258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor  if (!SFile)
296998258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor    return 0;
2970f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
297188145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
297288145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff  return FEnt->getModificationTime();
2973ee9405e807d7c447c0143c2bd865b759192e97b3Steve Naroff}
2974f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
2975b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
2976b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor  if (!tu)
2977b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor    return 0;
2978f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
2979a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
2980f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
2981b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor  FileManager &FMgr = CXXUnit->getFileManager();
298239b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner  return const_cast<FileEntry *>(FMgr.getFile(file_name));
2983b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor}
2984f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
2985dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregorunsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) {
2986dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  if (!tu || !file)
2987dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor    return 0;
2988dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor
2989dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
2990dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  FileEntry *FEnt = static_cast<FileEntry *>(file);
2991dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor  return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2992dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor                                          .isFileMultipleIncludeGuarded(FEnt);
2993dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor}
2994dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor
2995fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C"
2996fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek
2997fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===//
2998fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek// CXCursor Operations.
2999fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===//
3000fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek
3001fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekstatic Decl *getDeclFromExpr(Stmt *E) {
3002c2954616fbd11f5a6117236f58420029b773a639Argyrios Kyrtzidis  if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
3003db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor    return getDeclFromExpr(CE->getSubExpr());
3004db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor
3005fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek  if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
3006fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek    return RefExpr->getDecl();
300738f28c1189142429384996409fffbc57f67b5c60Douglas Gregor  if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
300838f28c1189142429384996409fffbc57f67b5c60Douglas Gregor    return RefExpr->getDecl();
3009fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek  if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
3010fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek    return ME->getMemberDecl();
3011fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek  if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
3012fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek    return RE->getDecl();
3013db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor  if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
301412f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
3015db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor
3016fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek  if (CallExpr *CE = dyn_cast<CallExpr>(E))
3017fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek    return getDeclFromExpr(CE->getCallee());
30185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
301993798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor    if (!CE->isElidable())
302093798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor    return CE->getConstructor();
3021fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek  if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
3022fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek    return OME->getMethodDecl();
3023f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
3024db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor  if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
3025db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor    return PE->getProtocol();
3026c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor  if (SubstNonTypeTemplateParmPackExpr *NTTP
3027c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor                              = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3028c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor    return NTTP->getParameterPack();
302994d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor  if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
303094d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor    if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
303194d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor        isa<ParmVarDecl>(SizeOfPack->getPack()))
303294d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor      return SizeOfPack->getPack();
3033db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor
3034fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek  return 0;
3035fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek}
3036ee9405e807d7c447c0143c2bd865b759192e97b3Steve Naroff
3037c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbarstatic SourceLocation getLocationFromExpr(Expr *E) {
3038c2954616fbd11f5a6117236f58420029b773a639Argyrios Kyrtzidis  if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
3039c2954616fbd11f5a6117236f58420029b773a639Argyrios Kyrtzidis    return getLocationFromExpr(CE->getSubExpr());
3040c2954616fbd11f5a6117236f58420029b773a639Argyrios Kyrtzidis
3041c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar  if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
3042c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar    return /*FIXME:*/Msg->getLeftLoc();
3043c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
3044c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar    return DRE->getLocation();
304538f28c1189142429384996409fffbc57f67b5c60Douglas Gregor  if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E))
304638f28c1189142429384996409fffbc57f67b5c60Douglas Gregor    return RefExpr->getLocation();
3047c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar  if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
3048c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar    return Member->getMemberLoc();
3049c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar  if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
3050c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar    return Ivar->getLocation();
305194d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor  if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
305294d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor    return SizeOfPack->getPackLoc();
305394d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor
3054c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar  return E->getLocStart();
3055c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar}
3056c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar
3057fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekextern "C" {
3058f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
3059f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekunsigned clang_visitChildren(CXCursor parent,
3060b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor                             CXCursorVisitor visitor,
3061b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor                             CXClientData client_data) {
3062a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
306304a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor                          false);
3064b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor  return CursorVis.VisitChildren(parent);
3065b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor}
3066b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor
30673387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#ifndef __has_feature
30683387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#define __has_feature(x) 0
30693387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#endif
30703387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#if __has_feature(blocks)
30713387c65a094a02b2a94c05111d035a97d3d5c794David Chisnalltypedef enum CXChildVisitResult
30723387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall     (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
30733387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall
30743387c65a094a02b2a94c05111d035a97d3d5c794David Chisnallstatic enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
30753387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall    CXClientData client_data) {
30763387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall  CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
30773387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall  return block(cursor, parent);
30783387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall}
30793387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#else
30803387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall// If we are compiled with a compiler that doesn't have native blocks support,
30813387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall// define and call the block manually, so the
30823387c65a094a02b2a94c05111d035a97d3d5c794David Chisnalltypedef struct _CXChildVisitResult
30833387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall{
30843387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall	void *isa;
30853387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall	int flags;
30863387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall	int reserved;
30879e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar	enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
30889e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar                                         CXCursor);
30893387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall} *CXCursorVisitorBlock;
30903387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall
30913387c65a094a02b2a94c05111d035a97d3d5c794David Chisnallstatic enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
30923387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall    CXClientData client_data) {
30933387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall  CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
30943387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall  return block->invoke(block, cursor, parent);
30953387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall}
30963387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#endif
30973387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall
30983387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall
30999e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbarunsigned clang_visitChildrenWithBlock(CXCursor parent,
31009e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar                                      CXCursorVisitorBlock block) {
31013387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall  return clang_visitChildren(parent, visitWithBlock, block);
31023387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall}
31033387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall
310478205d4bada39d95097e766af9eb30cdd0159461Douglas Gregorstatic CXString getDeclSpelling(Decl *D) {
310578205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor  NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
3106e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor  if (!ND) {
31075f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
3108e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor      if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3109e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor        return createCXString(Property->getIdentifier()->getName());
3110e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor
3111ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek    return createCXString("");
3112e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor  }
3113e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor
311478205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor  if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
3115ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek    return createCXString(OMD->getSelector().getAsString());
3116f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
311778205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor  if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
311878205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor    // No, this isn't the same as the code below. getIdentifier() is non-virtual
311978205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor    // and returns different names. NamedDecl returns the class name and
312078205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor    // ObjCCategoryImplDecl returns the category name.
3121ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek    return createCXString(CIMP->getIdentifier()->getNameStart());
3122f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
31230a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor  if (isa<UsingDirectiveDecl>(D))
31240a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor    return createCXString("");
31250a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor
312650aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek  llvm::SmallString<1024> S;
312750aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek  llvm::raw_svector_ostream os(S);
312850aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek  ND->printName(os);
312950aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek
313050aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek  return createCXString(os.str());
313178205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor}
3132f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
31339ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXString clang_getCursorSpelling(CXCursor C) {
31347eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor  if (clang_isTranslationUnit(C.kind))
3135a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    return clang_getTranslationUnitSpelling(
3136a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                            static_cast<CXTranslationUnit>(C.data[2]));
31377eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor
3138f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff  if (clang_isReference(C.kind)) {
3139f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff    switch (C.kind) {
3140acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar    case CXCursor_ObjCSuperClassRef: {
31412e331b938b38057e333fab0ba841130ea8467794Douglas Gregor      ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
3142ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek      return createCXString(Super->getIdentifier()->getNameStart());
3143acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar    }
3144acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar    case CXCursor_ObjCClassRef: {
31451adb082a709f7b588f03672999294e061234b2cfDouglas Gregor      ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
3146ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek      return createCXString(Class->getIdentifier()->getNameStart());
3147acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar    }
3148acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar    case CXCursor_ObjCProtocolRef: {
314978db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor      ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
3150f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor      assert(OID && "getCursorSpelling(): Missing protocol decl");
3151ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek      return createCXString(OID->getIdentifier()->getNameStart());
3152acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar    }
31533064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek    case CXCursor_CXXBaseSpecifier: {
31543064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek      CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
31553064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek      return createCXString(B->getType().getAsString());
31563064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek    }
31577d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor    case CXCursor_TypeRef: {
31587d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor      TypeDecl *Type = getCursorTypeRef(C).first;
31597d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor      assert(Type && "Missing type decl");
31607d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor
3161ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek      return createCXString(getCursorContext(C).getTypeDeclType(Type).
3162ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek                              getAsString());
31637d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor    }
31640b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    case CXCursor_TemplateRef: {
31650b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor      TemplateDecl *Template = getCursorTemplateRef(C).first;
31666931900f43cea558c6974075256c07728dbfecc6Douglas Gregor      assert(Template && "Missing template decl");
31670b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
31680b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor      return createCXString(Template->getNameAsString());
31690b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    }
31706931900f43cea558c6974075256c07728dbfecc6Douglas Gregor
31716931900f43cea558c6974075256c07728dbfecc6Douglas Gregor    case CXCursor_NamespaceRef: {
31726931900f43cea558c6974075256c07728dbfecc6Douglas Gregor      NamedDecl *NS = getCursorNamespaceRef(C).first;
31736931900f43cea558c6974075256c07728dbfecc6Douglas Gregor      assert(NS && "Missing namespace decl");
31746931900f43cea558c6974075256c07728dbfecc6Douglas Gregor
31756931900f43cea558c6974075256c07728dbfecc6Douglas Gregor      return createCXString(NS->getNameAsString());
31766931900f43cea558c6974075256c07728dbfecc6Douglas Gregor    }
31777d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor
3178a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    case CXCursor_MemberRef: {
3179a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      FieldDecl *Field = getCursorMemberRef(C).first;
3180a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      assert(Field && "Missing member decl");
3181a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
3182a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      return createCXString(Field->getNameAsString());
3183a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    }
3184a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
318536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    case CXCursor_LabelRef: {
318636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor      LabelStmt *Label = getCursorLabelRef(C).first;
318736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor      assert(Label && "Missing label");
318836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor
3189ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner      return createCXString(Label->getName());
319036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    }
319136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor
31921f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    case CXCursor_OverloadedDeclRef: {
31931f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
31941f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      if (Decl *D = Storage.dyn_cast<Decl *>()) {
31951f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor        if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
31961f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor          return createCXString(ND->getNameAsString());
31971f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor        return createCXString("");
31981f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      }
31991f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
32001f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor        return createCXString(E->getName().getAsString());
32011f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      OverloadedTemplateStorage *Ovl
32021f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor        = Storage.get<OverloadedTemplateStorage*>();
32031f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      if (Ovl->size() == 0)
32041f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor        return createCXString("");
32051f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      return createCXString((*Ovl->begin())->getNameAsString());
32061f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    }
32071f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
3208acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar    default:
3209ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek      return createCXString("<not implemented>");
3210f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff    }
3211f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff  }
321297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor
321397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor  if (clang_isExpression(C.kind)) {
321497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor    Decl *D = getDeclFromExpr(getCursorExpr(C));
321597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor    if (D)
321678205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor      return getDeclSpelling(D);
3217ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek    return createCXString("");
321897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor  }
321997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor
322036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor  if (clang_isStatement(C.kind)) {
322136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    Stmt *S = getCursorStmt(C);
322236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
3223ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner      return createCXString(Label->getName());
322436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor
322536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    return createCXString("");
322636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor  }
322736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor
32289b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth  if (C.kind == CXCursor_MacroExpansion)
32299e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth    return createCXString(getCursorMacroExpansion(C)->getName()
32304ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor                                                           ->getNameStart());
32314ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor
3232572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor  if (C.kind == CXCursor_MacroDefinition)
3233572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor    return createCXString(getCursorMacroDefinition(C)->getName()
3234572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor                                                           ->getNameStart());
3235572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor
3236ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor  if (C.kind == CXCursor_InclusionDirective)
3237ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor    return createCXString(getCursorInclusionDirective(C)->getFileName());
3238ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor
323960cbfacd947590f83257a4191566dda92fbbde69Douglas Gregor  if (clang_isDeclaration(C.kind))
324060cbfacd947590f83257a4191566dda92fbbde69Douglas Gregor    return getDeclSpelling(getCursorDecl(C));
3241e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek
3242ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek  return createCXString("");
3243f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff}
3244f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff
3245358559d8d7b458c5f64941842383a16e61f0828dDouglas GregorCXString clang_getCursorDisplayName(CXCursor C) {
3246358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  if (!clang_isDeclaration(C.kind))
3247358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    return clang_getCursorSpelling(C);
3248358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3249358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  Decl *D = getCursorDecl(C);
3250358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  if (!D)
3251358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    return createCXString("");
3252358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3253358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
3254358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3255358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    D = FunTmpl->getTemplatedDecl();
3256358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3257358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3258358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    llvm::SmallString<64> Str;
3259358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    llvm::raw_svector_ostream OS(Str);
3260358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    OS << Function->getNameAsString();
3261358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    if (Function->getPrimaryTemplate())
3262358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      OS << "<>";
3263358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    OS << "(";
3264358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3265358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      if (I)
3266358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor        OS << ", ";
3267358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3268358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    }
3269358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3270358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    if (Function->isVariadic()) {
3271358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      if (Function->getNumParams())
3272358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor        OS << ", ";
3273358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      OS << "...";
3274358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    }
3275358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    OS << ")";
3276358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    return createCXString(OS.str());
3277358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  }
3278358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3279358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3280358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    llvm::SmallString<64> Str;
3281358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    llvm::raw_svector_ostream OS(Str);
3282358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    OS << ClassTemplate->getNameAsString();
3283358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    OS << "<";
3284358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3285358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3286358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      if (I)
3287358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor        OS << ", ";
3288358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3289358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      NamedDecl *Param = Params->getParam(I);
3290358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      if (Param->getIdentifier()) {
3291358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor        OS << Param->getIdentifier()->getName();
3292358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor        continue;
3293358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      }
3294358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3295358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      // There is no parameter name, which makes this tricky. Try to come up
3296358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      // with something useful that isn't too long.
3297358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3298358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor        OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3299358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      else if (NonTypeTemplateParmDecl *NTTP
3300358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor                                    = dyn_cast<NonTypeTemplateParmDecl>(Param))
3301358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor        OS << NTTP->getType().getAsString(Policy);
3302358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      else
3303358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor        OS << "template<...> class";
3304358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    }
3305358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3306358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    OS << ">";
3307358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    return createCXString(OS.str());
3308358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  }
3309358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3310358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  if (ClassTemplateSpecializationDecl *ClassSpec
3311358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor                              = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3312358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    // If the type was explicitly written, use that.
3313358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3314358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor      return createCXString(TSInfo->getType().getAsString(Policy));
3315358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3316358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    llvm::SmallString<64> Str;
3317358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    llvm::raw_svector_ostream OS(Str);
3318358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    OS << ClassSpec->getNameAsString();
3319358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    OS << TemplateSpecializationType::PrintTemplateArgumentList(
3320910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                      ClassSpec->getTemplateArgs().data(),
3321910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                      ClassSpec->getTemplateArgs().size(),
3322358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor                                                                Policy);
3323358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor    return createCXString(OS.str());
3324358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  }
3325358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3326358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor  return clang_getCursorSpelling(C);
3327358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor}
3328358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor
3329e68fff6fc083c6270d835216a3de0b82c6ef0310Ted KremenekCXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
333089922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff  switch (Kind) {
3331e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_FunctionDecl:
3332e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("FunctionDecl");
3333e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_TypedefDecl:
3334e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("TypedefDecl");
3335e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_EnumDecl:
3336e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("EnumDecl");
3337e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_EnumConstantDecl:
3338e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("EnumConstantDecl");
3339e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_StructDecl:
3340e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("StructDecl");
3341e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_UnionDecl:
3342e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("UnionDecl");
3343e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ClassDecl:
3344e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ClassDecl");
3345e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_FieldDecl:
3346e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("FieldDecl");
3347e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_VarDecl:
3348e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("VarDecl");
3349e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ParmDecl:
3350e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ParmDecl");
3351e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCInterfaceDecl:
3352e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCInterfaceDecl");
3353e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCCategoryDecl:
3354e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCCategoryDecl");
3355e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCProtocolDecl:
3356e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCProtocolDecl");
3357e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCPropertyDecl:
3358e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCPropertyDecl");
3359e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCIvarDecl:
3360e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCIvarDecl");
3361e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCInstanceMethodDecl:
3362e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCInstanceMethodDecl");
3363e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCClassMethodDecl:
3364e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCClassMethodDecl");
3365e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCImplementationDecl:
3366e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCImplementationDecl");
3367e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCCategoryImplDecl:
3368e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCCategoryImplDecl");
33698bd5a69999cfd06b6b5a58fdd04e4f802b2df5a4Ted Kremenek  case CXCursor_CXXMethod:
33708bd5a69999cfd06b6b5a58fdd04e4f802b2df5a4Ted Kremenek      return createCXString("CXXMethod");
3371e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_UnexposedDecl:
3372e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("UnexposedDecl");
3373e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCSuperClassRef:
3374e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCSuperClassRef");
3375e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCProtocolRef:
3376e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCProtocolRef");
3377e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCClassRef:
3378e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCClassRef");
3379e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_TypeRef:
3380e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("TypeRef");
33810b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor  case CXCursor_TemplateRef:
33820b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor      return createCXString("TemplateRef");
33836931900f43cea558c6974075256c07728dbfecc6Douglas Gregor  case CXCursor_NamespaceRef:
33846931900f43cea558c6974075256c07728dbfecc6Douglas Gregor    return createCXString("NamespaceRef");
3385a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor  case CXCursor_MemberRef:
3386a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    return createCXString("MemberRef");
338736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor  case CXCursor_LabelRef:
338836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    return createCXString("LabelRef");
33891f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  case CXCursor_OverloadedDeclRef:
33901f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    return createCXString("OverloadedDeclRef");
3391e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_UnexposedExpr:
3392e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("UnexposedExpr");
33931ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek  case CXCursor_BlockExpr:
33941ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek      return createCXString("BlockExpr");
3395e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_DeclRefExpr:
3396e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("DeclRefExpr");
3397e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_MemberRefExpr:
3398e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("MemberRefExpr");
3399e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_CallExpr:
3400e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("CallExpr");
3401e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_ObjCMessageExpr:
3402e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("ObjCMessageExpr");
3403e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_UnexposedStmt:
3404e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("UnexposedStmt");
340536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor  case CXCursor_LabelStmt:
340636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor      return createCXString("LabelStmt");
3407e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_InvalidFile:
3408e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("InvalidFile");
3409292db6401f040795db3ea4e00fc02622d6c3ba1dTed Kremenek  case CXCursor_InvalidCode:
3410292db6401f040795db3ea4e00fc02622d6c3ba1dTed Kremenek    return createCXString("InvalidCode");
3411e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_NoDeclFound:
3412e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("NoDeclFound");
3413e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_NotImplemented:
3414e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("NotImplemented");
3415e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  case CXCursor_TranslationUnit:
3416e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek      return createCXString("TranslationUnit");
3417e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek  case CXCursor_UnexposedAttr:
3418e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek      return createCXString("UnexposedAttr");
3419e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek  case CXCursor_IBActionAttr:
3420e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek      return createCXString("attribute(ibaction)");
34219f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor  case CXCursor_IBOutletAttr:
34229f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor     return createCXString("attribute(iboutlet)");
3423857e918a8a40deb128840308a318bf623d68295fTed Kremenek  case CXCursor_IBOutletCollectionAttr:
3424857e918a8a40deb128840308a318bf623d68295fTed Kremenek      return createCXString("attribute(iboutletcollection)");
34256639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis  case CXCursor_CXXFinalAttr:
34266639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis      return createCXString("attribute(final)");
34276639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis  case CXCursor_CXXOverrideAttr:
34286639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis      return createCXString("attribute(override)");
34299f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor  case CXCursor_PreprocessingDirective:
34309f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor    return createCXString("preprocessing directive");
3431572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor  case CXCursor_MacroDefinition:
3432572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor    return createCXString("macro definition");
34339b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth  case CXCursor_MacroExpansion:
34349b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth    return createCXString("macro expansion");
3435ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor  case CXCursor_InclusionDirective:
3436ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor    return createCXString("inclusion directive");
34378f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek  case CXCursor_Namespace:
34388f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek    return createCXString("Namespace");
3439a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek  case CXCursor_LinkageSpec:
3440a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek    return createCXString("LinkageSpec");
34413064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek  case CXCursor_CXXBaseSpecifier:
34423064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek    return createCXString("C++ base class specifier");
344301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case CXCursor_Constructor:
344401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    return createCXString("CXXConstructor");
344501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case CXCursor_Destructor:
344601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    return createCXString("CXXDestructor");
344701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor  case CXCursor_ConversionFunction:
344801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor    return createCXString("CXXConversion");
3449fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case CXCursor_TemplateTypeParameter:
3450fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return createCXString("TemplateTypeParameter");
3451fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case CXCursor_NonTypeTemplateParameter:
3452fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return createCXString("NonTypeTemplateParameter");
3453fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case CXCursor_TemplateTemplateParameter:
3454fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return createCXString("TemplateTemplateParameter");
3455fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  case CXCursor_FunctionTemplate:
3456fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return createCXString("FunctionTemplate");
345739d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor  case CXCursor_ClassTemplate:
345839d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor    return createCXString("ClassTemplate");
345974dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor  case CXCursor_ClassTemplatePartialSpecialization:
346074dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor    return createCXString("ClassTemplatePartialSpecialization");
34616931900f43cea558c6974075256c07728dbfecc6Douglas Gregor  case CXCursor_NamespaceAlias:
34626931900f43cea558c6974075256c07728dbfecc6Douglas Gregor    return createCXString("NamespaceAlias");
34630a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor  case CXCursor_UsingDirective:
34640a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor    return createCXString("UsingDirective");
34657e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor  case CXCursor_UsingDeclaration:
34667e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor    return createCXString("UsingDeclaration");
3467162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  case CXCursor_TypeAliasDecl:
3468352697a87bca664356f21a838b162084013625eaDouglas Gregor    return createCXString("TypeAliasDecl");
3469352697a87bca664356f21a838b162084013625eaDouglas Gregor  case CXCursor_ObjCSynthesizeDecl:
3470352697a87bca664356f21a838b162084013625eaDouglas Gregor    return createCXString("ObjCSynthesizeDecl");
3471352697a87bca664356f21a838b162084013625eaDouglas Gregor  case CXCursor_ObjCDynamicDecl:
3472352697a87bca664356f21a838b162084013625eaDouglas Gregor    return createCXString("ObjCDynamicDecl");
347389922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff  }
3474e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek
3475deb06bd3566e18f677e76bc435d478b033fe328bTed Kremenek  llvm_unreachable("Unhandled CXCursorKind");
3476a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  return createCXString((const char*) 0);
3477600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff}
347889922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff
3479064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidisstruct GetCursorData {
3480064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis  SourceLocation TokenBeginLoc;
34814b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis  bool PointsAtMacroArgExpansion;
3482064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis  CXCursor &BestCursor;
3483064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis
34844b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis  GetCursorData(SourceManager &SM,
34854b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis                SourceLocation tokenBegin, CXCursor &outputCursor)
34864b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis    : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
34874b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis    PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
34884b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis  }
3489064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis};
3490064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis
34914b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidisstatic enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
34924b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis                                                CXCursor parent,
34934b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis                                                CXClientData client_data) {
3494064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis  GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3495064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis  CXCursor *BestCursor = &Data->BestCursor;
34964b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis
34974b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis  // If we point inside a macro argument we should provide info of what the
34984b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis  // token is so use the actual cursor, don't replace it with a macro expansion
34994b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis  // cursor.
35004b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis  if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
35014b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis    return CXChildVisit_Recurse;
3502064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis
3503064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis  if (clang_isExpression(cursor.kind) &&
3504064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis      clang_isDeclaration(BestCursor->kind)) {
3505064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis    Decl *D = getCursorDecl(*BestCursor);
3506064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis
3507064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis    // Avoid having the cursor of an expression replace the declaration cursor
3508064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis    // when the expression source range overlaps the declaration range.
3509064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis    // This can happen for C++ constructor expressions whose range generally
3510064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis    // include the variable declaration, e.g.:
3511064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis    //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3512064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis    if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3513064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis        D->getLocation() == Data->TokenBeginLoc)
3514064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis      return CXChildVisit_Break;
3515064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis  }
3516064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis
351793798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor  // If our current best cursor is the construction of a temporary object,
351893798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor  // don't replace that cursor with a type reference, because we want
351993798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor  // clang_getCursor() to point at the constructor.
352093798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor  if (clang_isExpression(BestCursor->kind) &&
352193798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor      isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
352293798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor      cursor.kind == CXCursor_TypeRef)
352393798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor    return CXChildVisit_Recurse;
352493798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor
352585fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor  // Don't override a preprocessing cursor with another preprocessing
352685fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor  // cursor; we want the outermost preprocessing cursor.
352785fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor  if (clang_isPreprocessing(cursor.kind) &&
352885fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor      clang_isPreprocessing(BestCursor->kind))
352985fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor    return CXChildVisit_Recurse;
353085fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor
353133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  *BestCursor = cursor;
353233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  return CXChildVisit_Recurse;
353333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor}
3534e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek
3535b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3536b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor  if (!TU)
3537f462989fe8d6f59ab2d7d0fe2b4b96292ce706eaTed Kremenek    return clang_getNullCursor();
3538e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek
3539a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
3540bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3541bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
3542a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  // Translate the given source location to make it point at the beginning of
3543a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  // the token under the cursor.
3544a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek  SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3545a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek
3546a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek  // Guard against an invalid SourceLocation, or we may assert in one
3547a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek  // of the following calls.
3548a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek  if (SLoc.isInvalid())
3549a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek    return clang_getNullCursor();
3550a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek
355140749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor  bool Logging = getenv("LIBCLANG_LOGGING");
3552a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
3553a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor                                    CXXUnit->getASTContext().getLangOptions());
3554a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor
355533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
355633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  if (SLoc.isValid()) {
355733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor    // FIXME: Would be great to have a "hint" cursor, then walk from that
355833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor    // hint cursor upward until we find a cursor whose source range encloses
355933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor    // the region of interest, rather than starting from the translation unit.
35604b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis    GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
3561a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    CXCursor Parent = clang_getTranslationUnitCursor(TU);
3562064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis    CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
356308e0bc16b3312c27e87d33be7dcf3d4fe5bdd2e2Douglas Gregor                            /*VisitPreprocessorLast=*/true,
356408e0bc16b3312c27e87d33be7dcf3d4fe5bdd2e2Douglas Gregor                            SourceLocation(SLoc));
356533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor    CursorVis.VisitChildren(Parent);
356677128ddd3077fc045751a55bb3226802b15d5510Steve Naroff  }
356740749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor
356840749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor  if (Logging) {
356940749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    CXFile SearchFile;
357040749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    unsigned SearchLine, SearchColumn;
357140749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    CXFile ResultFile;
357240749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    unsigned ResultLine, ResultColumn;
35736653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    CXString SearchFileName, ResultFileName, KindSpelling, USR;
35746653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
357540749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
357640749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor
357720174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth    clang_getExpansionLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
357820174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth    clang_getExpansionLocation(ResultLoc, &ResultFile, &ResultLine,
357920174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth                               &ResultColumn, 0);
358040749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    SearchFileName = clang_getFileName(SearchFile);
358140749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    ResultFileName = clang_getFileName(ResultFile);
358240749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    KindSpelling = clang_getCursorKindSpelling(Result.kind);
35836653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    USR = clang_getCursorUSR(Result);
35846653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
358540749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor            clang_getCString(SearchFileName), SearchLine, SearchColumn,
358640749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor            clang_getCString(KindSpelling),
35876653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor            clang_getCString(ResultFileName), ResultLine, ResultColumn,
35886653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor            clang_getCString(USR), IsDef);
358940749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    clang_disposeString(SearchFileName);
359040749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    clang_disposeString(ResultFileName);
359140749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor    clang_disposeString(KindSpelling);
35926653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    clang_disposeString(USR);
35930aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor
35940aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor    CXCursor Definition = clang_getCursorDefinition(Result);
35950aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor    if (!clang_equalCursors(Definition, clang_getNullCursor())) {
35960aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor      CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
35970aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor      CXString DefinitionKindSpelling
35980aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor                                = clang_getCursorKindSpelling(Definition.kind);
35990aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor      CXFile DefinitionFile;
36000aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor      unsigned DefinitionLine, DefinitionColumn;
360120174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth      clang_getExpansionLocation(DefinitionLoc, &DefinitionFile,
360220174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth                                 &DefinitionLine, &DefinitionColumn, 0);
36030aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor      CXString DefinitionFileName = clang_getFileName(DefinitionFile);
36040aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor      fprintf(stderr, "  -> %s(%s:%d:%d)\n",
36050aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor              clang_getCString(DefinitionKindSpelling),
36060aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor              clang_getCString(DefinitionFileName),
36070aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor              DefinitionLine, DefinitionColumn);
36080aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor      clang_disposeString(DefinitionFileName);
36090aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor      clang_disposeString(DefinitionKindSpelling);
36100aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor    }
361140749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor  }
361240749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor
3613e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek  return Result;
361477128ddd3077fc045751a55bb3226802b15d5510Steve Naroff}
361577128ddd3077fc045751a55bb3226802b15d5510Steve Naroff
3616738855554394a6afcf39cc8345fd22c3756b8dd0Ted KremenekCXCursor clang_getNullCursor(void) {
36175bfb8c128c2ac8eb4032afc180cdc400a0f953caDouglas Gregor  return MakeCXCursorInvalid(CXCursor_InvalidFile);
3618738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek}
3619738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek
3620738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenekunsigned clang_equalCursors(CXCursor X, CXCursor Y) {
3621283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor  return X == Y;
3622738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek}
36230d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar
36249ce5584553054d0cb934940586aca0186e87fa57Douglas Gregorunsigned clang_hashCursor(CXCursor C) {
36259ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor  unsigned Index = 0;
36269ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor  if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
36279ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor    Index = 1;
36289ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor
36299ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor  return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
36309ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor                                        std::make_pair(C.kind, C.data[Index]));
36319ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor}
36329ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor
36339ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isInvalid(enum CXCursorKind K) {
363477128ddd3077fc045751a55bb3226802b15d5510Steve Naroff  return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
363577128ddd3077fc045751a55bb3226802b15d5510Steve Naroff}
363677128ddd3077fc045751a55bb3226802b15d5510Steve Naroff
36379ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isDeclaration(enum CXCursorKind K) {
363889922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff  return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
363989922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff}
36402d4d629d8a0de5112c7ae9d05c03ddbf6dcd956aSteve Naroff
36419ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isReference(enum CXCursorKind K) {
3642f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff  return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3643f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff}
3644f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff
364597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregorunsigned clang_isExpression(enum CXCursorKind K) {
364697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor  return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
364797b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor}
364897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor
364997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregorunsigned clang_isStatement(enum CXCursorKind K) {
365097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor  return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
365197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor}
365297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor
36538be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregorunsigned clang_isAttribute(enum CXCursorKind K) {
36548be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor    return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
36558be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor}
36568be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor
36577eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregorunsigned clang_isTranslationUnit(enum CXCursorKind K) {
36587eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor  return K == CXCursor_TranslationUnit;
36597eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor}
36607eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor
36619f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregorunsigned clang_isPreprocessing(enum CXCursorKind K) {
36629f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor  return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
36639f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor}
36649f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor
3665ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenekunsigned clang_isUnexposed(enum CXCursorKind K) {
3666ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek  switch (K) {
3667ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek    case CXCursor_UnexposedDecl:
3668ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek    case CXCursor_UnexposedExpr:
3669ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek    case CXCursor_UnexposedStmt:
3670ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek    case CXCursor_UnexposedAttr:
3671ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek      return true;
3672ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek    default:
3673ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek      return false;
3674ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek  }
3675ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek}
3676ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek
36779ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXCursorKind clang_getCursorKind(CXCursor C) {
36789efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff  return C.kind;
36799efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff}
36809efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff
368198258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas GregorCXSourceLocation clang_getCursorLocation(CXCursor C) {
368298258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor  if (clang_isReference(C.kind)) {
3683f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    switch (C.kind) {
3684f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek    case CXCursor_ObjCSuperClassRef: {
3685f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor      std::pair<ObjCInterfaceDecl *, SourceLocation> P
3686f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor        = getCursorObjCSuperClassRef(C);
3687a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3688f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    }
3689f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor
3690f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek    case CXCursor_ObjCProtocolRef: {
3691f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor      std::pair<ObjCProtocolDecl *, SourceLocation> P
3692f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor        = getCursorObjCProtocolRef(C);
3693a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3694f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    }
3695f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor
3696f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek    case CXCursor_ObjCClassRef: {
3697f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor      std::pair<ObjCInterfaceDecl *, SourceLocation> P
3698f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor        = getCursorObjCClassRef(C);
3699a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3700f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    }
37017d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor
3702f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek    case CXCursor_TypeRef: {
37037d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor      std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
3704a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
37057d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor    }
37060b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
37070b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    case CXCursor_TemplateRef: {
37080b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor      std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
37090b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
37100b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    }
37110b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
37126931900f43cea558c6974075256c07728dbfecc6Douglas Gregor    case CXCursor_NamespaceRef: {
37136931900f43cea558c6974075256c07728dbfecc6Douglas Gregor      std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
37146931900f43cea558c6974075256c07728dbfecc6Douglas Gregor      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
37156931900f43cea558c6974075256c07728dbfecc6Douglas Gregor    }
37166931900f43cea558c6974075256c07728dbfecc6Douglas Gregor
3717a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    case CXCursor_MemberRef: {
3718a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
3719a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
3720a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    }
3721a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
37223064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek    case CXCursor_CXXBaseSpecifier: {
37231b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor      CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
37241b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor      if (!BaseSpec)
37251b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor        return clang_getNullLocation();
37261b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor
37271b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor      if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
37281b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor        return cxloc::translateSourceLocation(getCursorContext(C),
37291b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor                                            TSInfo->getTypeLoc().getBeginLoc());
37301b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor
37311b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor      return cxloc::translateSourceLocation(getCursorContext(C),
37321b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor                                        BaseSpec->getSourceRange().getBegin());
37333064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek    }
3734f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
373536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    case CXCursor_LabelRef: {
373636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor      std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
373736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor      return cxloc::translateSourceLocation(getCursorContext(C), P.second);
373836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    }
373936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor
37401f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    case CXCursor_OverloadedDeclRef:
37411f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      return cxloc::translateSourceLocation(getCursorContext(C),
37421f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor                                          getCursorOverloadedDeclRef(C).second);
37431f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
3744f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    default:
3745f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor      // FIXME: Need a way to enumerate all non-reference cases.
3746f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor      llvm_unreachable("Missed a reference kind");
3747f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    }
374898258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor  }
374997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor
375097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor  if (clang_isExpression(C.kind))
3751f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek    return cxloc::translateSourceLocation(getCursorContext(C),
375297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor                                   getLocationFromExpr(getCursorExpr(C)));
375397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor
375436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor  if (clang_isStatement(C.kind))
375536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    return cxloc::translateSourceLocation(getCursorContext(C),
375636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor                                          getCursorStmt(C)->getLocStart());
375736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor
37589f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor  if (C.kind == CXCursor_PreprocessingDirective) {
37599f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor    SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
37609f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor    return cxloc::translateSourceLocation(getCursorContext(C), L);
37619f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor  }
37624807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor
37639b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth  if (C.kind == CXCursor_MacroExpansion) {
37644ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor    SourceLocation L
37659e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth      = cxcursor::getCursorMacroExpansion(C)->getSourceRange().getBegin();
37664807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor    return cxloc::translateSourceLocation(getCursorContext(C), L);
37674807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor  }
3768572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor
3769572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor  if (C.kind == CXCursor_MacroDefinition) {
3770572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor    SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
3771572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor    return cxloc::translateSourceLocation(getCursorContext(C), L);
3772572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor  }
3773ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor
3774ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor  if (C.kind == CXCursor_InclusionDirective) {
3775ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor    SourceLocation L
3776ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor      = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
3777ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor    return cxloc::translateSourceLocation(getCursorContext(C), L);
3778ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor  }
3779ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor
37809a700d277c38d9afaa7cb3fe93a714bfe9b62eecTed Kremenek  if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl)
37815352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor    return clang_getNullLocation();
378298258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor
3783f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  Decl *D = getCursorDecl(C);
3784f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  SourceLocation Loc = D->getLocation();
3785f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3786f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    Loc = Class->getClassLoc();
3787007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek  // FIXME: Multiple variables declared in a single declaration
3788007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek  // currently lack the information needed to correctly determine their
3789007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek  // ranges when accounting for the type-specifier.  We use context
3790007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek  // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3791007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek  // and if so, whether it is the first decl.
3792007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3793007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    if (!cxcursor::isFirstInDeclGroup(C))
3794007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek      Loc = VD->getLocation();
3795007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek  }
3796007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek
37972ca54feee89d7277fb967e3247a64f40ef155a82Douglas Gregor  return cxloc::translateSourceLocation(getCursorContext(C), Loc);
379888145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff}
3799a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor
3800a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor} // end extern "C"
3801a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor
3802a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorstatic SourceRange getRawCursorExtent(CXCursor C) {
3803a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor  if (clang_isReference(C.kind)) {
3804a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor    switch (C.kind) {
3805a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor    case CXCursor_ObjCSuperClassRef:
3806a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor      return  getCursorObjCSuperClassRef(C).second;
3807f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
3808a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor    case CXCursor_ObjCProtocolRef:
3809a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor      return getCursorObjCProtocolRef(C).second;
3810f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
3811a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor    case CXCursor_ObjCClassRef:
3812a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor      return getCursorObjCClassRef(C).second;
38137d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor
3814a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor    case CXCursor_TypeRef:
3815a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor      return getCursorTypeRef(C).second;
38160b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
38170b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    case CXCursor_TemplateRef:
38180b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor      return getCursorTemplateRef(C).second;
38190b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
38206931900f43cea558c6974075256c07728dbfecc6Douglas Gregor    case CXCursor_NamespaceRef:
38216931900f43cea558c6974075256c07728dbfecc6Douglas Gregor      return getCursorNamespaceRef(C).second;
3822a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
3823a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    case CXCursor_MemberRef:
3824a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor      return getCursorMemberRef(C).second;
3825a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
38263064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek    case CXCursor_CXXBaseSpecifier:
38271b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor      return getCursorCXXBaseSpecifier(C)->getSourceRange();
3828f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
382936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    case CXCursor_LabelRef:
383036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor      return getCursorLabelRef(C).second;
383136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor
38321f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    case CXCursor_OverloadedDeclRef:
38331f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      return getCursorOverloadedDeclRef(C).second;
38341f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
3835a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor    default:
3836a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor      // FIXME: Need a way to enumerate all non-reference cases.
3837a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor      llvm_unreachable("Missed a reference kind");
3838a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor    }
3839a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor  }
384097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor
384197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor  if (clang_isExpression(C.kind))
3842a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor    return getCursorExpr(C)->getSourceRange();
384333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor
384433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor  if (clang_isStatement(C.kind))
3845a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor    return getCursorStmt(C)->getSourceRange();
3846f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
38476639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis  if (clang_isAttribute(C.kind))
38486639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis    return getCursorAttr(C)->getRange();
38496639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis
3850a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  if (C.kind == CXCursor_PreprocessingDirective)
3851a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor    return cxcursor::getCursorPreprocessingDirective(C);
38524807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor
38539b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth  if (C.kind == CXCursor_MacroExpansion)
38549e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth    return cxcursor::getCursorMacroExpansion(C)->getSourceRange();
3855572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor
3856a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  if (C.kind == CXCursor_MacroDefinition)
3857a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor    return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
3858ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor
3859ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor  if (C.kind == CXCursor_InclusionDirective)
3860ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor    return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
3861ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor
3862007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek  if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
3863007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    Decl *D = cxcursor::getCursorDecl(C);
3864007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    SourceRange R = D->getSourceRange();
3865007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    // FIXME: Multiple variables declared in a single declaration
3866007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    // currently lack the information needed to correctly determine their
3867007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    // ranges when accounting for the type-specifier.  We use context
3868007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
3869007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    // and if so, whether it is the first decl.
3870007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3871007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek      if (!cxcursor::isFirstInDeclGroup(C))
3872007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek        R.setBegin(VD->getLocation());
3873007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    }
3874007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek    return R;
3875007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek  }
38766653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor  return SourceRange();
38776653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor}
38786653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor
38796653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor/// \brief Retrieves the "raw" cursor extent, which is then extended to include
38806653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor/// the decl-specifier-seq for declarations.
38816653798ff5ce6deb58112777e21307ccc453133dDouglas Gregorstatic SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
38826653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor  if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
38836653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    Decl *D = cxcursor::getCursorDecl(C);
38846653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    SourceRange R = D->getSourceRange();
38852494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor
38862494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    // Adjust the start of the location for declarations preceded by
38872494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    // declaration specifiers.
38882494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    SourceLocation StartLoc;
38896653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
38902494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor      if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
38912494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor        StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
38922494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
38932494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor      if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
38942494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor        StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
38952494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    }
38966653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor
38972494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    if (StartLoc.isValid() && R.getBegin().isValid() &&
38982494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor        SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
38992494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor      R.setBegin(StartLoc);
39002494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor
39012494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    // FIXME: Multiple variables declared in a single declaration
39022494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    // currently lack the information needed to correctly determine their
39032494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    // ranges when accounting for the type-specifier.  We use context
39042494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
39052494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    // and if so, whether it is the first decl.
39062494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
39072494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor      if (!cxcursor::isFirstInDeclGroup(C))
39082494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor        R.setBegin(VD->getLocation());
39096653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    }
39106653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor
39116653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor    return R;
39126653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor  }
39136653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor
39146653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor  return getRawCursorExtent(C);
39156653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor}
3916a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor
3917a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorextern "C" {
3918a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor
3919a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas GregorCXSourceRange clang_getCursorExtent(CXCursor C) {
3920a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  SourceRange R = getRawCursorExtent(C);
3921a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  if (R.isInvalid())
39225352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor    return clang_getNullRange();
3923f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
3924a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor  return cxloc::translateSourceRange(getCursorContext(C), R);
3925a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor}
3926c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor
3927c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas GregorCXCursor clang_getCursorReferenced(CXCursor C) {
3928b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor  if (clang_isInvalid(C.kind))
3929b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor    return clang_getNullCursor();
3930f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
3931a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  CXTranslationUnit tu = getCursorTU(C);
39321f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (clang_isDeclaration(C.kind)) {
39331f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    Decl *D = getCursorDecl(C);
39341f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
3935a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
39361f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
3937a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
39381f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    if (ObjCForwardProtocolDecl *Protocols
39391f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor                                        = dyn_cast<ObjCForwardProtocolDecl>(D))
3940a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
39415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
3942e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor      if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3943e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor        return MakeCXCursor(Property, tu);
3944e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor
3945c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor    return C;
39461f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  }
39471f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
394897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor  if (clang_isExpression(C.kind)) {
39491f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    Expr *E = getCursorExpr(C);
39501f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    Decl *D = getDeclFromExpr(E);
395197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor    if (D)
3952a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(D, tu);
39531f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
39541f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
3955a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCursorOverloadedDeclRef(Ovl, tu);
39561f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
395797b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor    return clang_getNullCursor();
395897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor  }
395997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor
396036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor  if (clang_isStatement(C.kind)) {
396136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    Stmt *S = getCursorStmt(C);
396236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
396337c2e9664316b013b9a86f841f143f19ffbc0a02Ted Kremenek      if (LabelDecl *label = Goto->getLabel())
396437c2e9664316b013b9a86f841f143f19ffbc0a02Ted Kremenek        if (LabelStmt *labelS = label->getStmt())
396537c2e9664316b013b9a86f841f143f19ffbc0a02Ted Kremenek        return MakeCXCursor(labelS, getCursorDecl(C), tu);
396636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor
396736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    return clang_getNullCursor();
396836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor  }
396936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor
39709b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth  if (C.kind == CXCursor_MacroExpansion) {
39719e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth    if (MacroDefinition *Def = getCursorMacroExpansion(C)->getDefinition())
3972a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeMacroDefinitionCursor(Def, tu);
3973bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor  }
3974bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor
3975c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor  if (!clang_isReference(C.kind))
3976c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor    return clang_getNullCursor();
3977f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
3978c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor  switch (C.kind) {
3979c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor    case CXCursor_ObjCSuperClassRef:
3980a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
3981f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
3982f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek    case CXCursor_ObjCProtocolRef: {
3983a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
3984f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
3985f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek    case CXCursor_ObjCClassRef:
3986a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
39877d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor
3988f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek    case CXCursor_TypeRef:
3989a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(getCursorTypeRef(C).first, tu );
39900b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
39910b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor    case CXCursor_TemplateRef:
3992a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(getCursorTemplateRef(C).first, tu );
39930b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor
39946931900f43cea558c6974075256c07728dbfecc6Douglas Gregor    case CXCursor_NamespaceRef:
3995a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
39966931900f43cea558c6974075256c07728dbfecc6Douglas Gregor
3997a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor    case CXCursor_MemberRef:
3998a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(getCursorMemberRef(C).first, tu );
3999a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor
40003064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek    case CXCursor_CXXBaseSpecifier: {
40013064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek      CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
40023064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek      return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4003a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                                                         tu ));
40043064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek    }
4005f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
400636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor    case CXCursor_LabelRef:
400736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor      // FIXME: We end up faking the "parent" declaration here because we
400836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor      // don't want to make CXCursor larger.
400936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor      return MakeCXCursor(getCursorLabelRef(C).first,
4010a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek               static_cast<ASTUnit*>(tu->TUData)->getASTContext()
4011a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                          .getTranslationUnitDecl(),
4012a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                          tu);
401336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor
40141f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    case CXCursor_OverloadedDeclRef:
40151f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor      return C;
40161f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
4017c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor    default:
4018c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor      // We would prefer to enumerate all non-reference cursor kinds here.
4019c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor      llvm_unreachable("Unhandled reference cursor kind");
4020c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor      break;
4021c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor    }
4022c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor  }
4023f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4024c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor  return clang_getNullCursor();
4025c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor}
4026c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor
4027b699866820102a69d83d6ac6941985c5ef4e8c40Douglas GregorCXCursor clang_getCursorDefinition(CXCursor C) {
4028b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor  if (clang_isInvalid(C.kind))
4029b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor    return clang_getNullCursor();
4030f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4031a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  CXTranslationUnit TU = getCursorTU(C);
4032f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4033b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  bool WasReference = false;
403497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor  if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4035b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    C = clang_getCursorReferenced(C);
4036b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    WasReference = true;
4037b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  }
4038b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
40399b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth  if (C.kind == CXCursor_MacroExpansion)
4040bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor    return clang_getCursorReferenced(C);
4041bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor
4042b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  if (!clang_isDeclaration(C.kind))
4043b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4044b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4045b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  Decl *D = getCursorDecl(C);
4046b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  if (!D)
4047b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4048f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4049b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  switch (D->getKind()) {
4050b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  // Declaration kinds that don't really separate the notions of
4051b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  // declaration and definition.
4052b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::Namespace:
4053b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::Typedef:
4054162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  case Decl::TypeAlias:
40553e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  case Decl::TypeAliasTemplate:
4056b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::TemplateTypeParm:
4057b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::EnumConstant:
4058b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::Field:
4059d98114647e16796a976b04af79975b4f0eacf22bBenjamin Kramer  case Decl::IndirectField:
4060b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCIvar:
4061b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCAtDefsField:
4062b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ImplicitParam:
4063b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ParmVar:
4064b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::NonTypeTemplateParm:
4065b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::TemplateTemplateParm:
4066b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCCategoryImpl:
4067b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCImplementation:
40686206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara  case Decl::AccessSpec:
4069b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::LinkageSpec:
4070b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCPropertyImpl:
4071b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::FileScopeAsm:
4072b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::StaticAssert:
4073b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::Block:
4074ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  case Decl::Label:  // FIXME: Is this right??
4075af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  case Decl::ClassScopeFunctionSpecialization:
4076b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return C;
4077b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4078b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  // Declaration kinds that don't make any sense here, but are
4079b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  // nonetheless harmless.
4080b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::TranslationUnit:
4081b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    break;
4082b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4083b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  // Declaration kinds for which the definition is not resolvable.
4084b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::UnresolvedUsingTypename:
4085b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::UnresolvedUsingValue:
4086b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    break;
4087b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4088b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::UsingDirective:
4089b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor    return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4090a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                        TU);
4091b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4092b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::NamespaceAlias:
4093a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4094b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4095b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::Enum:
4096b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::Record:
4097b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::CXXRecord:
4098b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ClassTemplateSpecialization:
4099b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ClassTemplatePartialSpecialization:
4100952b017601f9c82b51119c3a1600f1312a833db9Douglas Gregor    if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4101a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(Def, TU);
4102b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4103b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4104b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::Function:
4105b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::CXXMethod:
4106b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::CXXConstructor:
4107b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::CXXDestructor:
4108b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::CXXConversion: {
4109b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    const FunctionDecl *Def = 0;
4110b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (cast<FunctionDecl>(D)->getBody(Def))
4111a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
4112b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4113b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  }
4114b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4115b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::Var: {
411631310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl    // Ask the variable if it has a definition.
411731310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl    if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
4118a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(Def, TU);
411931310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl    return clang_getNullCursor();
4120b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  }
4121f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4122b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::FunctionTemplate: {
4123b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    const FunctionDecl *Def = 0;
4124b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4125a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4126b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4127b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  }
4128f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4129b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ClassTemplate: {
4130b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4131952b017601f9c82b51119c3a1600f1312a833db9Douglas Gregor                                                            ->getDefinition())
41320b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor      return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4133a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                          TU);
4134b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4135b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  }
4136b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
41371f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  case Decl::Using:
41381f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4139a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                                       D->getLocation(), TU);
4140b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4141b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::UsingShadow:
4142b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getCursorDefinition(
4143f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek                       MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4144a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                                    TU));
4145b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4146b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCMethod: {
4147b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
4148b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (Method->isThisDeclarationADefinition())
4149b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor      return C;
4150b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4151b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    // Dig out the method definition in the associated
4152b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    // @implementation, if we have it.
4153b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    // FIXME: The ASTs should make finding the definition easier.
4154b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (ObjCInterfaceDecl *Class
4155b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor                       = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4156b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor      if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4157b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor        if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4158b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor                                                  Method->isInstanceMethod()))
4159b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor          if (Def->isThisDeclarationADefinition())
4160a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek            return MakeCXCursor(Def, TU);
4161b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4162b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4163b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  }
4164b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4165b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCCategory:
4166b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (ObjCCategoryImplDecl *Impl
4167b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor                               = cast<ObjCCategoryDecl>(D)->getImplementation())
4168a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(Impl, TU);
4169b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4170b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4171b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCProtocol:
4172b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (!cast<ObjCProtocolDecl>(D)->isForwardDecl())
4173b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor      return C;
4174b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4175b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4176b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCInterface:
4177b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    // There are two notions of a "definition" for an Objective-C
4178b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    // class: the interface and its implementation. When we resolved a
4179b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    // reference to an Objective-C class, produce the @interface as
4180b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    // the definition; when we were provided with the interface,
4181b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    // produce the @implementation as the definition.
4182b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (WasReference) {
4183b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor      if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
4184b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor        return C;
4185b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    } else if (ObjCImplementationDecl *Impl
4186b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor                              = cast<ObjCInterfaceDecl>(D)->getImplementation())
4187a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(Impl, TU);
4188b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4189f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4190b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCProperty:
4191b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    // FIXME: We don't really know where to find the
4192b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    // ObjCPropertyImplDecls that implement this property.
4193b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4194b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4195b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::ObjCCompatibleAlias:
4196b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (ObjCInterfaceDecl *Class
4197b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor          = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
4198b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor      if (!Class->isForwardDecl())
4199a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek        return MakeCXCursor(Class, TU);
4200f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4201b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4202b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
42031f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  case Decl::ObjCForwardProtocol:
42041f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
4205a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                                       D->getLocation(), TU);
4206b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
42071f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  case Decl::ObjCClass:
42089e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar    return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
4209a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                                       TU);
4210b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4211b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::Friend:
4212b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4213a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4214b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4215b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4216b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  case Decl::FriendTemplate:
4217b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4218a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4219b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return clang_getNullCursor();
4220b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  }
4221b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4222b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  return clang_getNullCursor();
4223b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor}
4224b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4225b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregorunsigned clang_isCursorDefinition(CXCursor C) {
4226b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  if (!clang_isDeclaration(C.kind))
4227b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor    return 0;
4228b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
4229b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor  return clang_getCursorDefinition(C) == C;
4230b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor}
4231b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor
42321a9d0503b67a499797141af0fd6d315d5045f0eaDouglas GregorCXCursor clang_getCanonicalCursor(CXCursor C) {
42331a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor  if (!clang_isDeclaration(C.kind))
42341a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor    return C;
42351a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor
4236e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis  if (Decl *D = getCursorDecl(C)) {
4237debb00f9ce1dd0f855d2b4fff3372b2ceeb20735Argyrios Kyrtzidis    if (ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
4238debb00f9ce1dd0f855d2b4fff3372b2ceeb20735Argyrios Kyrtzidis      if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4239debb00f9ce1dd0f855d2b4fff3372b2ceeb20735Argyrios Kyrtzidis        return MakeCXCursor(CatD, getCursorTU(C));
4240debb00f9ce1dd0f855d2b4fff3372b2ceeb20735Argyrios Kyrtzidis
4241e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis    if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4242e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis      if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
4243e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis        return MakeCXCursor(IFD, getCursorTU(C));
4244e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis
42451a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor    return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4246e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis  }
42471a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor
42481a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor  return C;
42491a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor}
42501a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor
42511f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregorunsigned clang_getNumOverloadedDecls(CXCursor C) {
42527c432dd959609a3689c2e4406450c092e6d76d6dDouglas Gregor  if (C.kind != CXCursor_OverloadedDeclRef)
42531f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    return 0;
42541f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
42551f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
42561f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
42571f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    return E->getNumDecls();
42581f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
42591f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (OverloadedTemplateStorage *S
42601f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor                              = Storage.dyn_cast<OverloadedTemplateStorage*>())
42611f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    return S->size();
42621f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
42631f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  Decl *D = Storage.get<Decl*>();
42641f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
4265826faa22bae112e01293a58534a40711043cce65Argyrios Kyrtzidis    return Using->shadow_size();
426695ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian  if (isa<ObjCClassDecl>(D))
426795ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    return 1;
42681f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
42691f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    return Protocols->protocol_size();
42701f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
42711f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  return 0;
42721f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor}
42731f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
42741f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas GregorCXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
42757c432dd959609a3689c2e4406450c092e6d76d6dDouglas Gregor  if (cursor.kind != CXCursor_OverloadedDeclRef)
42761f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    return clang_getNullCursor();
42771f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
42781f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (index >= clang_getNumOverloadedDecls(cursor))
42791f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    return clang_getNullCursor();
42801f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
4281a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  CXTranslationUnit TU = getCursorTU(cursor);
42821f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
42831f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
4284a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    return MakeCXCursor(E->decls_begin()[index], TU);
42851f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
42861f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (OverloadedTemplateStorage *S
42871f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor                              = Storage.dyn_cast<OverloadedTemplateStorage*>())
4288a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    return MakeCXCursor(S->begin()[index], TU);
42891f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
42901f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  Decl *D = Storage.get<Decl*>();
42911f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
42921f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    // FIXME: This is, unfortunately, linear time.
42931f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    UsingDecl::shadow_iterator Pos = Using->shadow_begin();
42941f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor    std::advance(Pos, index);
4295a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
42961f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  }
42971f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
429895ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    return MakeCXCursor(Classes->getForwardInterfaceDecl(), TU);
42991f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
4300a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    return MakeCXCursor(Protocols->protocol_begin()[index], TU);
43011f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
43021f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor  return clang_getNullCursor();
43031f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor}
43041f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor
43050d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbarvoid clang_getDefinitionSpellingAndExtent(CXCursor C,
43064ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff                                          const char **startBuf,
43074ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff                                          const char **endBuf,
43084ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff                                          unsigned *startLine,
43094ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff                                          unsigned *startColumn,
43104ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff                                          unsigned *endLine,
43119ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar                                          unsigned *endColumn) {
4312283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor  assert(getCursorDecl(C) && "CXCursor has null decl");
4313283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor  NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
43144ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff  FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
43154ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff  CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4316f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
43174ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff  SourceManager &SM = FD->getASTContext().getSourceManager();
43184ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff  *startBuf = SM.getCharacterData(Body->getLBracLoc());
43194ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff  *endBuf = SM.getCharacterData(Body->getRBracLoc());
43204ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff  *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
43214ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff  *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
43224ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff  *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
43234ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff  *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
43244ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff}
4325f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4326430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor
4327430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas GregorCXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4328430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor                                                unsigned PieceIndex) {
4329430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  RefNamePieces Pieces;
4330430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor
4331430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  switch (C.kind) {
4332430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  case CXCursor_MemberRefExpr:
4333430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor    if (MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
4334430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor      Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4335430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor                           E->getQualifierLoc().getSourceRange());
4336430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor    break;
4337430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor
4338430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  case CXCursor_DeclRefExpr:
4339430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor    if (DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
4340430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor      Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4341430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor                           E->getQualifierLoc().getSourceRange(),
4342430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor                           E->getExplicitTemplateArgsOpt());
4343430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor    break;
4344430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor
4345430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  case CXCursor_CallExpr:
4346430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor    if (CXXOperatorCallExpr *OCE =
4347430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor        dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
4348430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor      Expr *Callee = OCE->getCallee();
4349430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor      if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
4350430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor        Callee = ICE->getSubExpr();
4351430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor
4352430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor      if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
4353430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor        Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4354430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor                             DRE->getQualifierLoc().getSourceRange());
4355430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor    }
4356430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor    break;
4357430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor
4358430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  default:
4359430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor    break;
4360430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  }
4361430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor
4362430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  if (Pieces.empty()) {
4363430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor    if (PieceIndex == 0)
4364430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor      return clang_getCursorExtent(C);
4365430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  } else if (PieceIndex < Pieces.size()) {
4366430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor      SourceRange R = Pieces[PieceIndex];
4367430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor      if (R.isValid())
4368430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor        return cxloc::translateSourceRange(getCursorContext(C), R);
4369430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  }
4370430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor
4371430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor  return clang_getNullRange();
4372430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor}
4373430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor
43740a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregorvoid clang_enableStackTraces(void) {
43750a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  llvm::sys::PrintStackTraceOnErrorSignal();
43760a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor}
43770a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
4378995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbarvoid clang_executeOnThread(void (*fn)(void*), void *user_data,
4379995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar                           unsigned stack_size) {
4380995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar  llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4381995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar}
4382995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar
4383fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C"
4384fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek
4385fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===//
4386fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor// Token-based Operations.
4387fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor//===----------------------------------------------------------------------===//
4388fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor
4389fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor/* CXToken layout:
4390fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *   int_data[0]: a CXTokenKind
4391fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *   int_data[1]: starting token location
4392fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *   int_data[2]: token length
4393fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *   int_data[3]: reserved
4394f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek *   ptr_data: for identifiers and keywords, an IdentifierInfo*.
4395fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *   otherwise unused.
4396fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor */
4397fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregorextern "C" {
4398fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor
4399fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXTokenKind clang_getTokenKind(CXToken CXTok) {
4400fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  return static_cast<CXTokenKind>(CXTok.int_data[0]);
4401fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor}
4402fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor
4403fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4404fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  switch (clang_getTokenKind(CXTok)) {
4405fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  case CXToken_Identifier:
4406fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  case CXToken_Keyword:
4407fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    // We know we have an IdentifierInfo*, so use that.
4408ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek    return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
4409ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek                            ->getNameStart());
4410fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor
4411fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  case CXToken_Literal: {
4412fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    // We have stashed the starting pointer in the ptr_data field. Use it.
4413fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    const char *Text = static_cast<const char *>(CXTok.ptr_data);
44145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    return createCXString(StringRef(Text, CXTok.int_data[2]));
4415fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  }
4416f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4417fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  case CXToken_Punctuation:
4418fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  case CXToken_Comment:
4419fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    break;
4420fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  }
4421f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4422f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  // We have to find the starting buffer pointer the hard way, by
4423fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  // deconstructing the source location.
4424a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
4425fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  if (!CXXUnit)
4426ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek    return createCXString("");
4427f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4428fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4429fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  std::pair<FileID, unsigned> LocInfo
4430a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4431f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor  bool Invalid = false;
44325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Buffer
4433f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor    = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4434f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor  if (Invalid)
4435aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor    return createCXString("");
4436fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor
4437f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer  return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
4438fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor}
4439f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4440fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
4441a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
4442fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  if (!CXXUnit)
4443fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    return clang_getNullLocation();
4444f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4445fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4446fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor                        SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4447fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor}
4448fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor
4449fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
4450a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
44515352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  if (!CXXUnit)
44525352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor    return clang_getNullRange();
4453f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4454f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4455fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor                        SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4456fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor}
4457f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4458fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregorvoid clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4459fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor                    CXToken **Tokens, unsigned *NumTokens) {
4460fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  if (Tokens)
4461fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    *Tokens = 0;
4462fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  if (NumTokens)
4463fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    *NumTokens = 0;
4464f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4465a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
4466fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  if (!CXXUnit || !Tokens || !NumTokens)
4467fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    return;
4468f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4469bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4470bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor
447185b988fdfa6adab6d43e16efd19ad4f3f7e2b49bDaniel Dunbar  SourceRange R = cxloc::translateCXSourceRange(Range);
4472fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  if (R.isInvalid())
4473fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    return;
4474f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4475fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  SourceManager &SourceMgr = CXXUnit->getSourceManager();
4476fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  std::pair<FileID, unsigned> BeginLocInfo
4477fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    = SourceMgr.getDecomposedLoc(R.getBegin());
4478fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  std::pair<FileID, unsigned> EndLocInfo
4479fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    = SourceMgr.getDecomposedLoc(R.getEnd());
4480f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4481fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  // Cannot tokenize across files.
4482fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  if (BeginLocInfo.first != EndLocInfo.first)
4483fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    return;
4484f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4485f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek  // Create a lexer
4486f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor  bool Invalid = false;
44875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Buffer
4488f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor    = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
448947a3fcd4afe122b23f9e7b6148f147bfa460cfe8Douglas Gregor  if (Invalid)
449047a3fcd4afe122b23f9e7b6148f147bfa460cfe8Douglas Gregor    return;
4491aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor
4492fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4493fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor            CXXUnit->getASTContext().getLangOptions(),
4494f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer            Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4495fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  Lex.SetCommentRetentionState(true);
4496f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4497fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  // Lex tokens until we hit the end of the range.
4498f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer  const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
44995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CXToken, 32> CXTokens;
4500fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  Token Tok;
4501096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall  bool previousWasAt = false;
4502fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  do {
4503fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    // Lex the next token
4504fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    Lex.LexFromRawLexer(Tok);
4505fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    if (Tok.is(tok::eof))
4506fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor      break;
4507f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4508fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    // Initialize the CXToken.
4509fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    CXToken CXTok;
4510f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4511fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    //   - Common fields
4512fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4513fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    CXTok.int_data[2] = Tok.getLength();
4514fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    CXTok.int_data[3] = 0;
4515f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4516fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    //   - Kind-specific fields
4517fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    if (Tok.isLiteral()) {
4518fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor      CXTok.int_data[0] = CXToken_Literal;
4519fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor      CXTok.ptr_data = (void *)Tok.getLiteralData();
4520c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara    } else if (Tok.is(tok::raw_identifier)) {
4521aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor      // Lookup the identifier to determine whether we have a keyword.
4522fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor      IdentifierInfo *II
4523c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara        = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4524aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek
4525096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall      if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4526aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek        CXTok.int_data[0] = CXToken_Keyword;
4527aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek      }
4528aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek      else {
4529c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara        CXTok.int_data[0] = Tok.is(tok::identifier)
4530c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara          ? CXToken_Identifier
4531c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara          : CXToken_Keyword;
4532aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek      }
4533fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor      CXTok.ptr_data = II;
4534fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    } else if (Tok.is(tok::comment)) {
4535fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor      CXTok.int_data[0] = CXToken_Comment;
4536fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor      CXTok.ptr_data = 0;
4537fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    } else {
4538fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor      CXTok.int_data[0] = CXToken_Punctuation;
4539fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor      CXTok.ptr_data = 0;
4540fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    }
4541fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    CXTokens.push_back(CXTok);
4542096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall    previousWasAt = Tok.is(tok::at);
4543fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4544f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4545fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  if (CXTokens.empty())
4546fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor    return;
4547f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
4548fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4549fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4550fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor  *NumTokens = CXTokens.size();
4551fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor}
45520045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor
45536db610934bedc6896393c1e1099525b35380acd6Ted Kremenekvoid clang_disposeTokens(CXTranslationUnit TU,
45546db610934bedc6896393c1e1099525b35380acd6Ted Kremenek                         CXToken *Tokens, unsigned NumTokens) {
45556db610934bedc6896393c1e1099525b35380acd6Ted Kremenek  free(Tokens);
45566db610934bedc6896393c1e1099525b35380acd6Ted Kremenek}
45576db610934bedc6896393c1e1099525b35380acd6Ted Kremenek
45586db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} // end: extern "C"
45596db610934bedc6896393c1e1099525b35380acd6Ted Kremenek
45606db610934bedc6896393c1e1099525b35380acd6Ted Kremenek//===----------------------------------------------------------------------===//
45616db610934bedc6896393c1e1099525b35380acd6Ted Kremenek// Token annotation APIs.
45626db610934bedc6896393c1e1099525b35380acd6Ted Kremenek//===----------------------------------------------------------------------===//
45636db610934bedc6896393c1e1099525b35380acd6Ted Kremenek
45640045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregortypedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
4565fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekstatic enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4566fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek                                                     CXCursor parent,
4567fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek                                                     CXClientData client_data);
45686db610934bedc6896393c1e1099525b35380acd6Ted Kremeneknamespace {
45696db610934bedc6896393c1e1099525b35380acd6Ted Kremenekclass AnnotateTokensWorker {
45706db610934bedc6896393c1e1099525b35380acd6Ted Kremenek  AnnotateTokensData &Annotated;
457111949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek  CXToken *Tokens;
457211949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek  CXCursor *Cursors;
457311949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek  unsigned NumTokens;
4574fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  unsigned TokIdx;
45754419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor  unsigned PreprocessingTokIdx;
4576fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  CursorVisitor AnnotateVis;
4577fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  SourceManager &SrcMgr;
4578f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  bool HasContextSensitiveKeywords;
4579f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor
4580fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  bool MoreTokens() const { return TokIdx < NumTokens; }
4581fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  unsigned NextToken() const { return TokIdx; }
4582fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  void AdvanceToken() { ++TokIdx; }
4583fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  SourceLocation GetTokenLoc(unsigned tokI) {
4584fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4585fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  }
45865f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis  bool isFunctionMacroToken(unsigned tokI) const {
4587a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    return Tokens[tokI].int_data[3] != 0;
4588a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  }
45895f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis  SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
4590a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
4591a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  }
4592a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4593a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
45945f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis  void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
45955f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis                                             SourceRange);
4596fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
45976db610934bedc6896393c1e1099525b35380acd6Ted Kremenekpublic:
459811949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek  AnnotateTokensWorker(AnnotateTokensData &annotated,
4599fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek                       CXToken *tokens, CXCursor *cursors, unsigned numTokens,
4600a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                       CXTranslationUnit tu, SourceRange RegionOfInterest)
460111949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek    : Annotated(annotated), Tokens(tokens), Cursors(cursors),
46024419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
4603a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      AnnotateVis(tu,
460408e0bc16b3312c27e87d33be7dcf3d4fe5bdd2e2Douglas Gregor                  AnnotateTokensVisitor, this, true, RegionOfInterest),
4605f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
4606f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      HasContextSensitiveKeywords(false) { }
460711949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek
4608fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
46096db610934bedc6896393c1e1099525b35380acd6Ted Kremenek  enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
4610fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  void AnnotateTokens(CXCursor parent);
4611ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek  void AnnotateTokens() {
4612a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
4613ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek  }
4614f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor
4615f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  /// \brief Determine whether the annotator saw any cursors that have
4616f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  /// context-sensitive keywords.
4617f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  bool hasContextSensitiveKeywords() const {
4618f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    return HasContextSensitiveKeywords;
4619f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  }
46206db610934bedc6896393c1e1099525b35380acd6Ted Kremenek};
46216db610934bedc6896393c1e1099525b35380acd6Ted Kremenek}
46220045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor
4623fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekvoid AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
4624fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  // Walk the AST within the region of interest, annotating tokens
4625fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  // along the way.
4626fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  VisitChildren(parent);
4627fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
4628fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  for (unsigned I = 0 ; I < TokIdx ; ++I) {
462911949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek    AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
46304419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    if (Pos != Annotated.end() &&
46314419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor        (clang_isInvalid(Cursors[I].kind) ||
46324419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor         Pos->second.kind != CXCursor_PreprocessingDirective))
4633fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek      Cursors[I] = Pos->second;
4634fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  }
4635fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
4636fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  // Finish up annotating any tokens left.
4637fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  if (!MoreTokens())
4638fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    return;
463911949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek
4640fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  const CXCursor &C = clang_getNullCursor();
4641fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
4642fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
4643fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
464411949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek  }
464511949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek}
464611949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek
4647a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// \brief It annotates and advances tokens with a cursor until the comparison
4648a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis//// between the cursor location and the source range is the same as
4649a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// \arg compResult.
4650a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis///
4651a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
4652a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// Pass RangeOverlap to annotate tokens inside a range.
4653a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidisvoid AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
4654a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis                                               RangeComparisonResult compResult,
4655a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis                                               SourceRange range) {
4656a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  while (MoreTokens()) {
4657a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    const unsigned I = NextToken();
46585f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis    if (isFunctionMacroToken(I))
46595f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis      return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range);
4660a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4661a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    SourceLocation TokLoc = GetTokenLoc(I);
4662a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
4663a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      Cursors[I] = updateC;
4664a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      AdvanceToken();
4665a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      continue;
4666a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    }
4667a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    break;
4668a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  }
4669a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis}
4670a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4671a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// \brief Special annotation handling for macro argument tokens.
46725f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidisvoid AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
46735f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis                                               CXCursor updateC,
4674a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis                                               RangeComparisonResult compResult,
4675a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis                                               SourceRange range) {
46765f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis  assert(MoreTokens());
46775f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis  assert(isFunctionMacroToken(NextToken()) &&
4678a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis         "Should be called only for macro arg tokens");
4679a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4680a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  // This works differently than annotateAndAdvanceTokens; because expanded
4681a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  // macro arguments can have arbitrary translation-unit source order, we do not
4682a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  // advance the token index one by one until a token fails the range test.
4683a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  // We only advance once past all of the macro arg tokens if all of them
4684a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  // pass the range test. If one of them fails we keep the token index pointing
4685a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  // at the start of the macro arg tokens so that the failing token will be
4686a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  // annotated by a subsequent annotation try.
4687a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4688a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  bool atLeastOneCompFail = false;
4689a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4690a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  unsigned I = NextToken();
46915f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis  for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
46925f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis    SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
4693a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    if (TokLoc.isFileID())
4694a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      continue; // not macro arg token, it's parens or comma.
4695a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
4696a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
4697a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis        Cursors[I] = updateC;
4698a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    } else
4699a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      atLeastOneCompFail = true;
4700a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  }
4701a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4702a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  if (!atLeastOneCompFail)
4703a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    TokIdx = I; // All of the tokens were handled, advance beyond all of them.
4704a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis}
4705a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
47066db610934bedc6896393c1e1099525b35380acd6Ted Kremenekenum CXChildVisitResult
47074419b675577d7c281a659fab1fec10e1bfbe04c5Douglas GregorAnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
4708fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  CXSourceLocation Loc = clang_getCursorLocation(cursor);
47094419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor  SourceRange cursorRange = getRawCursorExtent(cursor);
471081d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor  if (cursorRange.isInvalid())
471181d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor    return CXChildVisit_Recurse;
4712f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor
4713f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  if (!HasContextSensitiveKeywords) {
4714f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    // Objective-C properties can have context-sensitive keywords.
4715f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    if (cursor.kind == CXCursor_ObjCPropertyDecl) {
4716f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      if (ObjCPropertyDecl *Property
4717f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor                  = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
4718f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
4719f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    }
4720f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    // Objective-C methods can have context-sensitive keywords.
4721f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
4722f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor             cursor.kind == CXCursor_ObjCClassMethodDecl) {
4723f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      if (ObjCMethodDecl *Method
4724f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor            = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4725f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        if (Method->getObjCDeclQualifier())
4726f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor          HasContextSensitiveKeywords = true;
4727f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        else {
4728f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor          for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
4729f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor                                           PEnd = Method->param_end();
4730f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor               P != PEnd; ++P) {
4731f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor            if ((*P)->getObjCDeclQualifier()) {
4732f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor              HasContextSensitiveKeywords = true;
4733f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor              break;
4734f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor            }
4735f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor          }
4736f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        }
4737f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      }
4738f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    }
4739f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    // C++ methods can have context-sensitive keywords.
4740f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    else if (cursor.kind == CXCursor_CXXMethod) {
4741f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      if (CXXMethodDecl *Method
4742f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor                  = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
4743f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
4744f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor          HasContextSensitiveKeywords = true;
4745f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      }
4746f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    }
4747f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    // C++ classes can have context-sensitive keywords.
4748f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    else if (cursor.kind == CXCursor_StructDecl ||
4749f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor             cursor.kind == CXCursor_ClassDecl ||
4750f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor             cursor.kind == CXCursor_ClassTemplate ||
4751f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor             cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
4752f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      if (Decl *D = getCursorDecl(cursor))
4753f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        if (D->hasAttr<FinalAttr>())
4754f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor          HasContextSensitiveKeywords = true;
4755f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    }
4756f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  }
4757f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor
47584419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor  if (clang_isPreprocessing(cursor.kind)) {
4759cea731a9cb7de3f473d60e5ea544e25621cebd76Chandler Carruth    // For macro expansions, just note where the beginning of the macro
4760cea731a9cb7de3f473d60e5ea544e25621cebd76Chandler Carruth    // expansion occurs.
47619b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth    if (cursor.kind == CXCursor_MacroExpansion) {
47624419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      Annotated[Loc.int_data] = cursor;
47634419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      return CXChildVisit_Recurse;
47644419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    }
47654419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor
47664419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    // Items in the preprocessing record are kept separate from items in
47674419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    // declarations, so we keep a separate token index.
47684419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    unsigned SavedTokIdx = TokIdx;
47694419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    TokIdx = PreprocessingTokIdx;
47704419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor
47714419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    // Skip tokens up until we catch up to the beginning of the preprocessing
47724419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    // entry.
47734419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    while (MoreTokens()) {
47744419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      const unsigned I = NextToken();
47754419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      SourceLocation TokLoc = GetTokenLoc(I);
47764419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
47774419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      case RangeBefore:
47784419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor        AdvanceToken();
47794419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor        continue;
47804419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      case RangeAfter:
47814419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      case RangeOverlap:
47824419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor        break;
47834419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      }
47844419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      break;
47854419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    }
47864419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor
47874419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    // Look at all of the tokens within this range.
47884419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    while (MoreTokens()) {
47894419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      const unsigned I = NextToken();
47904419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      SourceLocation TokLoc = GetTokenLoc(I);
47914419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
47924419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      case RangeBefore:
47934419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor        assert(0 && "Infeasible");
47944419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      case RangeAfter:
47954419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor        break;
47964419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      case RangeOverlap:
47974419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor        Cursors[I] = cursor;
47984419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor        AdvanceToken();
47994419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor        continue;
48004419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      }
48014419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor      break;
48024419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    }
48034419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor
48044419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    // Save the preprocessing token index; restore the non-preprocessing
48054419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    // token index.
48064419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    PreprocessingTokIdx = TokIdx;
48074419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor    TokIdx = SavedTokIdx;
48080045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor    return CXChildVisit_Recurse;
48090045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor  }
4810fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
4811fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  if (cursorRange.isInvalid())
4812fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    return CXChildVisit_Continue;
4813a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek
4814fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
4815fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
4816a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek  // Adjust the annotated range based specific declarations.
4817a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek  const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
4818a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek  if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
481923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek    Decl *D = cxcursor::getCursorDecl(cursor);
48202494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor
48212494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    SourceLocation StartLoc;
482223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek    if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
48232494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor      if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
48242494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor        StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
48252494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
48262494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor      if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
48272494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor        StartLoc = TI->getTypeLoc().getSourceRange().getBegin();
4828a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek    }
48292494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor
48302494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor    if (StartLoc.isValid() && L.isValid() &&
48312494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor        SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
48322494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor      cursorRange.setBegin(StartLoc);
4833a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek  }
483481d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor
48353f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek  // If the location of the cursor occurs within a macro instantiation, record
48363f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek  // the spelling location of the cursor in our annotation map.  We can then
48373f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek  // paper over the token labelings during a post-processing step to try and
48383f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek  // get cursor mappings for tokens that are the *arguments* of a macro
48393f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek  // instantiation.
48403f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek  if (L.isMacroID()) {
48413f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek    unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
48423f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek    // Only invalidate the old annotation if it isn't part of a preprocessing
48433f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek    // directive.  Here we assume that the default construction of CXCursor
48443f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek    // results in CXCursor.kind being an initialized value (i.e., 0).  If
48453f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek    // this isn't the case, we can fix by doing lookup + insertion.
48464419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor
48473f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek    CXCursor &oldC = Annotated[rawEncoding];
48483f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek    if (!clang_isPreprocessing(oldC.kind))
48493f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek      oldC = cursor;
48503f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek  }
48513f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek
4852fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  const enum CXCursorKind K = clang_getCursorKind(parent);
4853fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  const CXCursor updateC =
4854d8b0a84d586bc0a08695968acf2f169c9d01da69Ted Kremenek    (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
4855d8b0a84d586bc0a08695968acf2f169c9d01da69Ted Kremenek     ? clang_getNullCursor() : parent;
4856fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
4857a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
4858fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
48595517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis  // Avoid having the cursor of an expression "overwrite" the annotation of the
48605517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis  // variable declaration that it belongs to.
48615517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis  // This can happen for C++ constructor expressions whose range generally
48625517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis  // include the variable declaration, e.g.:
48635517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis  //  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
48645517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis  if (clang_isExpression(cursorK)) {
48655517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis    Expr *E = getCursorExpr(cursor);
48668ccac3de1335f1cfd7cea56ba1cefcf0b724ce3fArgyrios Kyrtzidis    if (Decl *D = getCursorParentDecl(cursor)) {
48675517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis      const unsigned I = NextToken();
48685517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis      if (E->getLocStart().isValid() && D->getLocation().isValid() &&
48695517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis          E->getLocStart() == D->getLocation() &&
48705517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis          E->getLocStart() == GetTokenLoc(I)) {
48715517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis        Cursors[I] = updateC;
48725517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis        AdvanceToken();
48735517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis      }
48745517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis    }
48755517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis  }
48765517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis
4877fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  // Visit children to get their cursor information.
4878fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  const unsigned BeforeChildren = NextToken();
4879fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  VisitChildren(cursor);
4880fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  const unsigned AfterChildren = NextToken();
4881fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
4882a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  // Scan the tokens that are at the end of the cursor, but are not captured
4883a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  // but the child cursors.
4884a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
48856db610934bedc6896393c1e1099525b35380acd6Ted Kremenek
4886fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  // Scan the tokens that are at the beginning of the cursor, but are not
4887fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  // capture by the child cursors.
4888fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
4889fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
4890fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek      break;
48914419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor
4892fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    Cursors[I] = cursor;
4893fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  }
4894fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
4895fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  return CXChildVisit_Continue;
48960045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor}
48970045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor
48986db610934bedc6896393c1e1099525b35380acd6Ted Kremenekstatic enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
48996db610934bedc6896393c1e1099525b35380acd6Ted Kremenek                                                     CXCursor parent,
49006db610934bedc6896393c1e1099525b35380acd6Ted Kremenek                                                     CXClientData client_data) {
49016db610934bedc6896393c1e1099525b35380acd6Ted Kremenek  return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
49026db610934bedc6896393c1e1099525b35380acd6Ted Kremenek}
49036db610934bedc6896393c1e1099525b35380acd6Ted Kremenek
49046628a614c504263ae539462f049d523dd07ac1baTed Kremeneknamespace {
4905a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4906a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// \brief Uses the macro expansions in the preprocessing record to find
4907a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// and mark tokens that are macro arguments. This info is used by the
4908a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// AnnotateTokensWorker.
4909a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidisclass MarkMacroArgTokensVisitor {
4910a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  SourceManager &SM;
4911a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  CXToken *Tokens;
4912a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  unsigned NumTokens;
4913a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  unsigned CurIdx;
4914a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4915a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidispublic:
4916a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  MarkMacroArgTokensVisitor(SourceManager &SM,
4917a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis                            CXToken *tokens, unsigned numTokens)
4918a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
4919a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4920a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
4921a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    if (cursor.kind != CXCursor_MacroExpansion)
4922a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      return CXChildVisit_Continue;
4923a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4924a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    SourceRange macroRange = getCursorMacroExpansion(cursor)->getSourceRange();
4925a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    if (macroRange.getBegin() == macroRange.getEnd())
4926a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      return CXChildVisit_Continue; // it's not a function macro.
4927a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4928a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    for (; CurIdx < NumTokens; ++CurIdx) {
4929a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
4930a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis                                        macroRange.getBegin()))
4931a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis        break;
4932a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    }
4933a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4934a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    if (CurIdx == NumTokens)
4935a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      return CXChildVisit_Break;
4936a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4937a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    for (; CurIdx < NumTokens; ++CurIdx) {
4938a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      SourceLocation tokLoc = getTokenLoc(CurIdx);
4939a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
4940a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis        break;
4941a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
49425f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis      setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
4943a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    }
4944a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4945a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    if (CurIdx == NumTokens)
4946a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis      return CXChildVisit_Break;
4947a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4948a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    return CXChildVisit_Continue;
4949a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  }
4950a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4951a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidisprivate:
4952a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  SourceLocation getTokenLoc(unsigned tokI) {
4953a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4954a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  }
4955a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
49565f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis  void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
4957a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    // The third field is reserved and currently not used. Use it here
4958a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    // to mark macro arg expanded tokens with their expanded locations.
4959a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    Tokens[tokI].int_data[3] = loc.getRawEncoding();
4960a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  }
4961a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis};
4962a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4963a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis} // end anonymous namespace
4964a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4965a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidisstatic CXChildVisitResult
4966a676379b26edc959193f9f919ba9c6d296a57824Argyrios KyrtzidisMarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
4967a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis                                  CXClientData client_data) {
4968a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
4969a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis                                                                     parent);
4970a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis}
4971a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
4972a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidisnamespace {
49736628a614c504263ae539462f049d523dd07ac1baTed Kremenek  struct clang_annotateTokens_Data {
49746628a614c504263ae539462f049d523dd07ac1baTed Kremenek    CXTranslationUnit TU;
49756628a614c504263ae539462f049d523dd07ac1baTed Kremenek    ASTUnit *CXXUnit;
49766628a614c504263ae539462f049d523dd07ac1baTed Kremenek    CXToken *Tokens;
49776628a614c504263ae539462f049d523dd07ac1baTed Kremenek    unsigned NumTokens;
49786628a614c504263ae539462f049d523dd07ac1baTed Kremenek    CXCursor *Cursors;
49796628a614c504263ae539462f049d523dd07ac1baTed Kremenek  };
4980ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek}
4981ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek
49826628a614c504263ae539462f049d523dd07ac1baTed Kremenek// This gets run a separate thread to avoid stack blowout.
49836628a614c504263ae539462f049d523dd07ac1baTed Kremenekstatic void clang_annotateTokensImpl(void *UserData) {
49846628a614c504263ae539462f049d523dd07ac1baTed Kremenek  CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
49856628a614c504263ae539462f049d523dd07ac1baTed Kremenek  ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
49866628a614c504263ae539462f049d523dd07ac1baTed Kremenek  CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
49876628a614c504263ae539462f049d523dd07ac1baTed Kremenek  const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
49886628a614c504263ae539462f049d523dd07ac1baTed Kremenek  CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
4989fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
49900396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor  // Determine the region of interest, which contains all of the tokens.
49910045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor  SourceRange RegionOfInterest;
49926628a614c504263ae539462f049d523dd07ac1baTed Kremenek  RegionOfInterest.setBegin(
49936628a614c504263ae539462f049d523dd07ac1baTed Kremenek    cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
49946628a614c504263ae539462f049d523dd07ac1baTed Kremenek  RegionOfInterest.setEnd(
49956628a614c504263ae539462f049d523dd07ac1baTed Kremenek    cxloc::translateSourceLocation(clang_getTokenLocation(TU,
49966628a614c504263ae539462f049d523dd07ac1baTed Kremenek                                                         Tokens[NumTokens-1])));
4997fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek
49980396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor  // A mapping from the source locations found when re-lexing or traversing the
49990396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor  // region of interest to the corresponding cursors.
50000045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor  AnnotateTokensData Annotated;
50016628a614c504263ae539462f049d523dd07ac1baTed Kremenek
5002fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  // Relex the tokens within the source range to look for preprocessing
50030396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor  // directives.
50049f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor  SourceManager &SourceMgr = CXXUnit->getSourceManager();
50059f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor  std::pair<FileID, unsigned> BeginLocInfo
50069f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor    = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
50079f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor  std::pair<FileID, unsigned> EndLocInfo
50089f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor    = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
50096628a614c504263ae539462f049d523dd07ac1baTed Kremenek
50105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Buffer;
50110396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor  bool Invalid = false;
50120396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor  if (BeginLocInfo.first == EndLocInfo.first &&
50130396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor      ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
50140396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor      !Invalid) {
50159f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor    Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
50169f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor              CXXUnit->getASTContext().getLangOptions(),
5017fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek              Buffer.begin(), Buffer.data() + BeginLocInfo.second,
50184ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor              Buffer.end());
50199f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor    Lex.SetCommentRetentionState(true);
50206628a614c504263ae539462f049d523dd07ac1baTed Kremenek
5021fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek    // Lex tokens in raw mode until we hit the end of the range, to avoid
50229f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor    // entering #includes or expanding macros.
50234807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor    while (true) {
50249f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor      Token Tok;
50259f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor      Lex.LexFromRawLexer(Tok);
50266628a614c504263ae539462f049d523dd07ac1baTed Kremenek
50279f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor    reprocess:
50289f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor      if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
50299f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        // We have found a preprocessing directive. Gobble it up so that we
50309e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar        // don't see it while preprocessing these tokens later, but keep track
50319e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar        // of all of the token locations inside this preprocessing directive so
50329e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar        // that we can annotate them appropriately.
50339f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        //
50349f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        // FIXME: Some simple tests here could identify macro definitions and
50359f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        // #undefs, to provide specific cursor kinds for those.
50365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner        SmallVector<SourceLocation, 32> Locations;
50379f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        do {
50389f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor          Locations.push_back(Tok.getLocation());
5039fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek          Lex.LexFromRawLexer(Tok);
50409f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
50416628a614c504263ae539462f049d523dd07ac1baTed Kremenek
50429f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        using namespace cxcursor;
50439f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        CXCursor Cursor
50446628a614c504263ae539462f049d523dd07ac1baTed Kremenek        = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
50456628a614c504263ae539462f049d523dd07ac1baTed Kremenek                                                       Locations.back()),
5046a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                                           TU);
50479f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
50489f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor          Annotated[Locations[I].getRawEncoding()] = Cursor;
50499f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        }
50506628a614c504263ae539462f049d523dd07ac1baTed Kremenek
50519f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        if (Tok.isAtStartOfLine())
50529f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor          goto reprocess;
50536628a614c504263ae539462f049d523dd07ac1baTed Kremenek
50549f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        continue;
50559f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor      }
50566628a614c504263ae539462f049d523dd07ac1baTed Kremenek
50574807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor      if (Tok.is(tok::eof))
50589f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor        break;
50599f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor    }
50604ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor  }
50616628a614c504263ae539462f049d523dd07ac1baTed Kremenek
5062a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5063a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    // Search and mark tokens that are macro argument expansions.
5064a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5065a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis                                      Tokens, NumTokens);
5066a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    CursorVisitor MacroArgMarker(TU,
5067a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis                                 MarkMacroArgTokensVisitorDelegate, &Visitor,
506808e0bc16b3312c27e87d33be7dcf3d4fe5bdd2e2Douglas Gregor                                 true, RegionOfInterest);
5069a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis    MacroArgMarker.visitPreprocessedEntitiesInRegion();
5070a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis  }
5071a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis
50720396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor  // Annotate all of the source locations in the region of interest that map to
5073fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  // a specific cursor.
5074fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek  AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
5075a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek                         TU, RegionOfInterest);
50766628a614c504263ae539462f049d523dd07ac1baTed Kremenek
50776c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek  // FIXME: We use a ridiculous stack size here because the data-recursion
50786c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek  // algorithm uses a large stack frame than the non-data recursive version,
50796c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek  // and AnnotationTokensWorker currently transforms the data-recursion
50806c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek  // algorithm back into a traditional recursion by explicitly calling
50816c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek  // VisitChildren().  We will need to remove this explicit recursive call.
50826628a614c504263ae539462f049d523dd07ac1baTed Kremenek  W.AnnotateTokens();
50836628a614c504263ae539462f049d523dd07ac1baTed Kremenek
5084f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  // If we ran into any entities that involve context-sensitive keywords,
5085f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  // take another pass through the tokens to mark them as such.
5086f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  if (W.hasContextSensitiveKeywords()) {
5087f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    for (unsigned I = 0; I != NumTokens; ++I) {
5088f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5089f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        continue;
5090f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor
5091f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5092f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5093f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        if (ObjCPropertyDecl *Property
50946628a614c504263ae539462f049d523dd07ac1baTed Kremenek            = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5095f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor          if (Property->getPropertyAttributesAsWritten() != 0 &&
5096f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor              llvm::StringSwitch<bool>(II->getName())
50976628a614c504263ae539462f049d523dd07ac1baTed Kremenek              .Case("readonly", true)
50986628a614c504263ae539462f049d523dd07ac1baTed Kremenek              .Case("assign", true)
5099f85e193739c953358c865005855253af4f68a497John McCall              .Case("unsafe_unretained", true)
51006628a614c504263ae539462f049d523dd07ac1baTed Kremenek              .Case("readwrite", true)
51016628a614c504263ae539462f049d523dd07ac1baTed Kremenek              .Case("retain", true)
51026628a614c504263ae539462f049d523dd07ac1baTed Kremenek              .Case("copy", true)
51036628a614c504263ae539462f049d523dd07ac1baTed Kremenek              .Case("nonatomic", true)
51046628a614c504263ae539462f049d523dd07ac1baTed Kremenek              .Case("atomic", true)
51056628a614c504263ae539462f049d523dd07ac1baTed Kremenek              .Case("getter", true)
51066628a614c504263ae539462f049d523dd07ac1baTed Kremenek              .Case("setter", true)
5107f85e193739c953358c865005855253af4f68a497John McCall              .Case("strong", true)
5108f85e193739c953358c865005855253af4f68a497John McCall              .Case("weak", true)
51096628a614c504263ae539462f049d523dd07ac1baTed Kremenek              .Default(false))
5110f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor            Tokens[I].int_data[0] = CXToken_Keyword;
5111f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        }
5112f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        continue;
5113f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      }
5114f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor
5115f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5116f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor          Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5117f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5118f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        if (llvm::StringSwitch<bool>(II->getName())
51196628a614c504263ae539462f049d523dd07ac1baTed Kremenek            .Case("in", true)
51206628a614c504263ae539462f049d523dd07ac1baTed Kremenek            .Case("out", true)
51216628a614c504263ae539462f049d523dd07ac1baTed Kremenek            .Case("inout", true)
51226628a614c504263ae539462f049d523dd07ac1baTed Kremenek            .Case("oneway", true)
51236628a614c504263ae539462f049d523dd07ac1baTed Kremenek            .Case("bycopy", true)
51246628a614c504263ae539462f049d523dd07ac1baTed Kremenek            .Case("byref", true)
51256628a614c504263ae539462f049d523dd07ac1baTed Kremenek            .Default(false))
5126f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor          Tokens[I].int_data[0] = CXToken_Keyword;
5127f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor        continue;
5128f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      }
51296639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis
51306639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis      if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
51316639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis          Cursors[I].kind == CXCursor_CXXOverrideAttr) {
51326639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis        Tokens[I].int_data[0] = CXToken_Keyword;
51336628a614c504263ae539462f049d523dd07ac1baTed Kremenek        continue;
5134f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor      }
5135f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor    }
5136f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor  }
5137fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor}
51386628a614c504263ae539462f049d523dd07ac1baTed Kremenek
51396628a614c504263ae539462f049d523dd07ac1baTed Kremenekextern "C" {
51406628a614c504263ae539462f049d523dd07ac1baTed Kremenek
51416628a614c504263ae539462f049d523dd07ac1baTed Kremenekvoid clang_annotateTokens(CXTranslationUnit TU,
51426628a614c504263ae539462f049d523dd07ac1baTed Kremenek                          CXToken *Tokens, unsigned NumTokens,
51436628a614c504263ae539462f049d523dd07ac1baTed Kremenek                          CXCursor *Cursors) {
51446628a614c504263ae539462f049d523dd07ac1baTed Kremenek
51456628a614c504263ae539462f049d523dd07ac1baTed Kremenek  if (NumTokens == 0 || !Tokens || !Cursors)
51466628a614c504263ae539462f049d523dd07ac1baTed Kremenek    return;
51476628a614c504263ae539462f049d523dd07ac1baTed Kremenek
51486628a614c504263ae539462f049d523dd07ac1baTed Kremenek  // Any token we don't specifically annotate will have a NULL cursor.
51496628a614c504263ae539462f049d523dd07ac1baTed Kremenek  CXCursor C = clang_getNullCursor();
51506628a614c504263ae539462f049d523dd07ac1baTed Kremenek  for (unsigned I = 0; I != NumTokens; ++I)
51516628a614c504263ae539462f049d523dd07ac1baTed Kremenek    Cursors[I] = C;
51526628a614c504263ae539462f049d523dd07ac1baTed Kremenek
51536628a614c504263ae539462f049d523dd07ac1baTed Kremenek  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
51546628a614c504263ae539462f049d523dd07ac1baTed Kremenek  if (!CXXUnit)
51556628a614c504263ae539462f049d523dd07ac1baTed Kremenek    return;
51566628a614c504263ae539462f049d523dd07ac1baTed Kremenek
51576628a614c504263ae539462f049d523dd07ac1baTed Kremenek  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
51586628a614c504263ae539462f049d523dd07ac1baTed Kremenek
51596628a614c504263ae539462f049d523dd07ac1baTed Kremenek  clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
51606628a614c504263ae539462f049d523dd07ac1baTed Kremenek  llvm::CrashRecoveryContext CRC;
51616628a614c504263ae539462f049d523dd07ac1baTed Kremenek  if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
51626628a614c504263ae539462f049d523dd07ac1baTed Kremenek                 GetSafetyThreadStackSize() * 2)) {
51636628a614c504263ae539462f049d523dd07ac1baTed Kremenek    fprintf(stderr, "libclang: crash detected while annotating tokens\n");
51646628a614c504263ae539462f049d523dd07ac1baTed Kremenek  }
51656628a614c504263ae539462f049d523dd07ac1baTed Kremenek}
51666628a614c504263ae539462f049d523dd07ac1baTed Kremenek
5167fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} // end: extern "C"
5168fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor
5169fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor//===----------------------------------------------------------------------===//
517016b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek// Operations for querying linkage of a cursor.
517116b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek//===----------------------------------------------------------------------===//
517216b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek
517316b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenekextern "C" {
517416b4259aecaa22b642d35d36fd89965ed700c1e0Ted KremenekCXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
51750396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor  if (!clang_isDeclaration(cursor.kind))
51760396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor    return CXLinkage_Invalid;
51770396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor
517816b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek  Decl *D = cxcursor::getCursorDecl(cursor);
517916b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek  if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
518016b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek    switch (ND->getLinkage()) {
518116b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek      case NoLinkage: return CXLinkage_NoLinkage;
518216b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek      case InternalLinkage: return CXLinkage_Internal;
518316b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek      case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
518416b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek      case ExternalLinkage: return CXLinkage_External;
518516b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek    };
518616b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek
518716b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek  return CXLinkage_Invalid;
518816b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek}
518916b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek} // end: extern "C"
519016b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek
519116b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek//===----------------------------------------------------------------------===//
519245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek// Operations for querying language of a cursor.
519345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek//===----------------------------------------------------------------------===//
519445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek
519545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenekstatic CXLanguageKind getDeclLanguage(const Decl *D) {
519645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek  switch (D->getKind()) {
519745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    default:
519845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek      break;
519945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ImplicitParam:
520045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCAtDefsField:
520145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCCategory:
520245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCCategoryImpl:
520345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCClass:
520445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCCompatibleAlias:
520545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCForwardProtocol:
520645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCImplementation:
520745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCInterface:
520845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCIvar:
520945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCMethod:
521045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCProperty:
521145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCPropertyImpl:
521245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ObjCProtocol:
521345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek      return CXLanguage_ObjC;
521445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::CXXConstructor:
521545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::CXXConversion:
521645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::CXXDestructor:
521745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::CXXMethod:
521845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::CXXRecord:
521945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ClassTemplate:
522045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ClassTemplatePartialSpecialization:
522145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::ClassTemplateSpecialization:
522245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::Friend:
522345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::FriendTemplate:
522445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::FunctionTemplate:
522545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::LinkageSpec:
522645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::Namespace:
522745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::NamespaceAlias:
522845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::NonTypeTemplateParm:
522945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::StaticAssert:
523045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::TemplateTemplateParm:
523145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::TemplateTypeParm:
523245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::UnresolvedUsingTypename:
523345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::UnresolvedUsingValue:
523445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::Using:
523545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::UsingDirective:
523645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    case Decl::UsingShadow:
523745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek      return CXLanguage_CPlusPlus;
523845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek  }
523945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek
524045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek  return CXLanguage_C;
524145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek}
524245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek
524345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenekextern "C" {
524458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor
524558ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregorenum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
524658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor  if (clang_isDeclaration(cursor.kind))
524758ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor    if (Decl *D = cxcursor::getCursorDecl(cursor)) {
52480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
524958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor        return CXAvailability_Available;
525058ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor
52510a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      switch (D->getAvailability()) {
52520a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      case AR_Available:
52530a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      case AR_NotYetIntroduced:
52540a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        return CXAvailability_Available;
52550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
52560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      case AR_Deprecated:
525758ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor        return CXAvailability_Deprecated;
52580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
52590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      case AR_Unavailable:
52600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor        return CXAvailability_NotAvailable;
52610a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor      }
526258ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor    }
52630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
526458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor  return CXAvailability_Available;
526558ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor}
526658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor
526745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted KremenekCXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
526845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek  if (clang_isDeclaration(cursor.kind))
526945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek    return getDeclLanguage(cxcursor::getCursorDecl(cursor));
527045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek
527145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek  return CXLanguage_Invalid;
527245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek}
52733910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor
52743910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor /// \brief If the given cursor is the "templated" declaration
52753910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor /// descibing a class or function template, return the class or
52763910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor /// function template.
52773910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregorstatic Decl *maybeGetTemplateCursor(Decl *D) {
52783910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor  if (!D)
52793910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor    return 0;
52803910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor
52813910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
52823910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor    if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
52833910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor      return FunTmpl;
52843910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor
52853910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor  if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
52863910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor    if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
52873910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor      return ClassTmpl;
52883910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor
52893910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor  return D;
52903910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor}
52913910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor
52922be5bc9ad3981347a000742f81b91ab3080f1214Douglas GregorCXCursor clang_getCursorSemanticParent(CXCursor cursor) {
52932be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor  if (clang_isDeclaration(cursor.kind)) {
52942be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor    if (Decl *D = getCursorDecl(cursor)) {
52952be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor      DeclContext *DC = D->getDeclContext();
52963910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor      if (!DC)
52973910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor        return clang_getNullCursor();
52983910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor
52993910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor      return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
53003910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor                          getCursorTU(cursor));
53012be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor    }
53022be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor  }
53032be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor
53042be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor  if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
53052be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor    if (Decl *D = getCursorDecl(cursor))
5306a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      return MakeCXCursor(D, getCursorTU(cursor));
53072be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor  }
53082be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor
53092be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor  return clang_getNullCursor();
53102be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor}
53112be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor
53122be5bc9ad3981347a000742f81b91ab3080f1214Douglas GregorCXCursor clang_getCursorLexicalParent(CXCursor cursor) {
53132be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor  if (clang_isDeclaration(cursor.kind)) {
53142be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor    if (Decl *D = getCursorDecl(cursor)) {
53152be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor      DeclContext *DC = D->getLexicalDeclContext();
53163910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor      if (!DC)
53173910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor        return clang_getNullCursor();
53183910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor
53193910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor      return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
53203910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor                          getCursorTU(cursor));
53212be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor    }
53222be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor  }
53232be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor
53242be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor  // FIXME: Note that we can't easily compute the lexical context of a
53252be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor  // statement or expression, so we return nothing.
53262be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor  return clang_getNullCursor();
53272be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor}
53282be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor
53299f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorstatic void CollectOverriddenMethods(DeclContext *Ctx,
53309f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor                                     ObjCMethodDecl *Method,
53315f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                            SmallVectorImpl<ObjCMethodDecl *> &Methods) {
53329f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (!Ctx)
53339f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    return;
53349f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53359f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  // If we have a class or category implementation, jump straight to the
53369f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  // interface.
53379f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
53389f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
53399f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53409f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
53419f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (!Container)
53429f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    return;
53439f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53449f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  // Check whether we have a matching method at this level.
53459f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
53469f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor                                                    Method->isInstanceMethod()))
53479f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    if (Method != Overridden) {
53489f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor      // We found an override at this level; there is no need to look
53499f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor      // into other protocols or categories.
53509f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor      Methods.push_back(Overridden);
53519f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor      return;
53529f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    }
53539f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53549f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
53559f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
53569f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor                                          PEnd = Protocol->protocol_end();
53579f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor         P != PEnd; ++P)
53589f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor      CollectOverriddenMethods(*P, Method, Methods);
53599f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  }
53609f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53619f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
53629f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
53639f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor                                          PEnd = Category->protocol_end();
53649f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor         P != PEnd; ++P)
53659f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor      CollectOverriddenMethods(*P, Method, Methods);
53669f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  }
53679f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53689f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
53699f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
53709f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor                                           PEnd = Interface->protocol_end();
53719f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor         P != PEnd; ++P)
53729f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor      CollectOverriddenMethods(*P, Method, Methods);
53739f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53749f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    for (ObjCCategoryDecl *Category = Interface->getCategoryList();
53759f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor         Category; Category = Category->getNextClassCategory())
53769f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor      CollectOverriddenMethods(Category, Method, Methods);
53779f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53789f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    // We only look into the superclass if we haven't found anything yet.
53799f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    if (Methods.empty())
53809f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor      if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
53819f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor        return CollectOverriddenMethods(Super, Method, Methods);
53829f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  }
53839f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor}
53849f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53859f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorvoid clang_getOverriddenCursors(CXCursor cursor,
53869f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor                                CXCursor **overridden,
53879f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor                                unsigned *num_overridden) {
53889f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (overridden)
53899f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    *overridden = 0;
53909f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (num_overridden)
53919f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    *num_overridden = 0;
53929f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (!overridden || !num_overridden)
53939f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    return;
53949f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53959f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (!clang_isDeclaration(cursor.kind))
53969f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    return;
53979f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
53989f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  Decl *D = getCursorDecl(cursor);
53999f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (!D)
54009f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    return;
54019f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
54029f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  // Handle C++ member functions.
5403a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek  CXTranslationUnit TU = getCursorTU(cursor);
54049f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
54059f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    *num_overridden = CXXMethod->size_overridden_methods();
54069f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    if (!*num_overridden)
54079f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor      return;
54089f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
54099f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    *overridden = new CXCursor [*num_overridden];
54109f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    unsigned I = 0;
54119f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    for (CXXMethodDecl::method_iterator
54129f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor              M = CXXMethod->begin_overridden_methods(),
54139f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor           MEnd = CXXMethod->end_overridden_methods();
54149f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor         M != MEnd; (void)++M, ++I)
5415a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek      (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
54169f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    return;
54179f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  }
54189f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
54199f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
54209f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (!Method)
54219f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    return;
54229f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
54239f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  // Handle Objective-C methods.
54245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<ObjCMethodDecl *, 4> Methods;
54259f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
54269f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
54279f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  if (Methods.empty())
54289f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor    return;
54299f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
54309f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  *num_overridden = Methods.size();
54319f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  *overridden = new CXCursor [Methods.size()];
54329f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  for (unsigned I = 0, N = Methods.size(); I != N; ++I)
5433a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    (*overridden)[I] = MakeCXCursor(Methods[I], TU);
54349f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor}
54359f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
54369f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorvoid clang_disposeOverriddenCursors(CXCursor *overridden) {
54379f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor  delete [] overridden;
54389f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor}
54399f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor
5440ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas GregorCXFile clang_getIncludedFile(CXCursor cursor) {
5441ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor  if (cursor.kind != CXCursor_InclusionDirective)
5442ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor    return 0;
5443ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor
5444ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor  InclusionDirective *ID = getCursorInclusionDirective(cursor);
5445ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor  return (void *)ID->getFile();
5446ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor}
5447ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor
544845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek} // end: extern "C"
544945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek
54509ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek
54519ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek//===----------------------------------------------------------------------===//
54529ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek// C++ AST instrospection.
54539ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek//===----------------------------------------------------------------------===//
54549ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek
54559ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenekextern "C" {
54569ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenekunsigned clang_CXXMethod_isStatic(CXCursor C) {
54579ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek  if (!clang_isDeclaration(C.kind))
54589ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek    return 0;
545949f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor
546049f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor  CXXMethodDecl *Method = 0;
546149f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor  Decl *D = cxcursor::getCursorDecl(C);
546249f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor  if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
546349f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor    Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
546449f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor  else
546549f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor    Method = dyn_cast_or_null<CXXMethodDecl>(D);
546649f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor  return (Method && Method->isStatic()) ? 1 : 0;
546740b492a43bac3ed0c465772aa6921d011cfc273fTed Kremenek}
5468b12903e1a4b8d1b611b8c7e4f910665d628e68cdTed Kremenek
5469211924b563aa31421836cee7655be729ad02733fDouglas Gregorunsigned clang_CXXMethod_isVirtual(CXCursor C) {
5470211924b563aa31421836cee7655be729ad02733fDouglas Gregor  if (!clang_isDeclaration(C.kind))
5471211924b563aa31421836cee7655be729ad02733fDouglas Gregor    return 0;
5472211924b563aa31421836cee7655be729ad02733fDouglas Gregor
5473211924b563aa31421836cee7655be729ad02733fDouglas Gregor  CXXMethodDecl *Method = 0;
5474211924b563aa31421836cee7655be729ad02733fDouglas Gregor  Decl *D = cxcursor::getCursorDecl(C);
5475211924b563aa31421836cee7655be729ad02733fDouglas Gregor  if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
5476211924b563aa31421836cee7655be729ad02733fDouglas Gregor    Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
5477211924b563aa31421836cee7655be729ad02733fDouglas Gregor  else
5478211924b563aa31421836cee7655be729ad02733fDouglas Gregor    Method = dyn_cast_or_null<CXXMethodDecl>(D);
5479211924b563aa31421836cee7655be729ad02733fDouglas Gregor  return (Method && Method->isVirtual()) ? 1 : 0;
5480211924b563aa31421836cee7655be729ad02733fDouglas Gregor}
54819ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek} // end: extern "C"
54829ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek
548345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek//===----------------------------------------------------------------------===//
548495f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek// Attribute introspection.
548595f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek//===----------------------------------------------------------------------===//
548695f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek
548795f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenekextern "C" {
548895f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted KremenekCXType clang_getIBOutletCollectionType(CXCursor C) {
548995f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek  if (C.kind != CXCursor_IBOutletCollectionAttr)
5490a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek    return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
549195f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek
549295f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek  IBOutletCollectionAttr *A =
549395f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek    cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
549495f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek
549518aa2ff4641847d7f8866e8c5912d4d0ddb858ceArgyrios Kyrtzidis  return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
549695f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek}
549795f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek} // end: extern "C"
549895f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek
549995f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek//===----------------------------------------------------------------------===//
550059fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek// Inspecting memory usage.
550159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek//===----------------------------------------------------------------------===//
550259fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
5503f787002478f09af1741fb0f82a562002e6799c49Ted Kremenektypedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
550459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
5505f787002478f09af1741fb0f82a562002e6799c49Ted Kremenekstatic inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
5506f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek                                              enum CXTUResourceUsageKind k,
5507ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek                                              unsigned long amount) {
5508f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek  CXTUResourceUsageEntry entry = { k, amount };
550959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  entries.push_back(entry);
551059fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek}
551159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
551259fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenekextern "C" {
551359fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
5514f787002478f09af1741fb0f82a562002e6799c49Ted Kremenekconst char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
551559fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  const char *str = "";
551659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  switch (kind) {
5517f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek    case CXTUResourceUsage_AST:
551859fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek      str = "ASTContext: expressions, declarations, and types";
551959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek      break;
5520f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek    case CXTUResourceUsage_Identifiers:
552159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek      str = "ASTContext: identifiers";
552259fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek      break;
5523f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek    case CXTUResourceUsage_Selectors:
552459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek      str = "ASTContext: selectors";
5525e294ab717fc9535429ca5d8f575d41ae4441d822Ted Kremenek      break;
5526f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek    case CXTUResourceUsage_GlobalCompletionResults:
55274e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek      str = "Code completion: cached global results";
5528e294ab717fc9535429ca5d8f575d41ae4441d822Ted Kremenek      break;
5529457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek    case CXTUResourceUsage_SourceManagerContentCache:
5530457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek      str = "SourceManager: content cache allocator";
5531457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek      break;
5532ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek    case CXTUResourceUsage_AST_SideTables:
5533ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek      str = "ASTContext: side tables";
5534ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek      break;
5535f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek    case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
5536f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek      str = "SourceManager: malloc'ed memory buffers";
5537f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek      break;
5538f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek    case CXTUResourceUsage_SourceManager_Membuffer_MMap:
5539f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek      str = "SourceManager: mmap'ed memory buffers";
5540f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek      break;
5541e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek    case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
5542e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek      str = "ExternalASTSource: malloc'ed memory buffers";
5543e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek      break;
5544e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek    case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
5545e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek      str = "ExternalASTSource: mmap'ed memory buffers";
5546e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek      break;
55475e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek    case CXTUResourceUsage_Preprocessor:
55485e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek      str = "Preprocessor: malloc'ed memory";
55495e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek      break;
55505e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek    case CXTUResourceUsage_PreprocessingRecord:
55515e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek      str = "Preprocessor: PreprocessingRecord";
55525e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek      break;
5553ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek    case CXTUResourceUsage_SourceManager_DataStructures:
5554ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek      str = "SourceManager: data structures and tables";
5555ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek      break;
5556d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek    case CXTUResourceUsage_Preprocessor_HeaderSearch:
5557d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek      str = "Preprocessor: header search tables";
5558d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek      break;
555959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  }
556059fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  return str;
556159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek}
556259fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
5563f787002478f09af1741fb0f82a562002e6799c49Ted KremenekCXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
556459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  if (!TU) {
5565f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek    CXTUResourceUsage usage = { (void*) 0, 0, 0 };
556659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek    return usage;
556759fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  }
556859fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
556959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
557059fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  llvm::OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
557159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  ASTContext &astContext = astUnit->getASTContext();
557259fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
557359fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  // How much memory is used by AST nodes and types?
5574f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
5575ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek    (unsigned long) astContext.getASTAllocatedMemory());
557659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
557759fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  // How much memory is used by identifiers?
5578f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
557959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek    (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
558059fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
558159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  // How much memory is used for selectors?
5582f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
558359fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek    (unsigned long) astContext.Selectors.getTotalMemory());
558459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
5585ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek  // How much memory is used by ASTContext's side tables?
5586ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
5587ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek    (unsigned long) astContext.getSideTableAllocatedMemory());
5588ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek
55894e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek  // How much memory is used for caching global code completion results?
55904e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek  unsigned long completionBytes = 0;
55914e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek  if (GlobalCodeCompletionAllocator *completionAllocator =
55924e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek      astUnit->getCachedCompletionAllocator().getPtr()) {
55935e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek    completionBytes = completionAllocator->getTotalMemory();
55944e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek  }
5595457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek  createCXTUResourceUsageEntry(*entries,
5596457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek                               CXTUResourceUsage_GlobalCompletionResults,
5597457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek                               completionBytes);
5598457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek
5599457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek  // How much memory is being used by SourceManager's content cache?
5600457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek  createCXTUResourceUsageEntry(*entries,
5601457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek          CXTUResourceUsage_SourceManagerContentCache,
5602457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek          (unsigned long) astContext.getSourceManager().getContentCacheSize());
5603f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek
5604f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek  // How much memory is being used by the MemoryBuffer's in SourceManager?
5605f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek  const SourceManager::MemoryBufferSizes &srcBufs =
5606f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek    astUnit->getSourceManager().getMemoryBufferSizes();
5607f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek
5608f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek  createCXTUResourceUsageEntry(*entries,
5609f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek                               CXTUResourceUsage_SourceManager_Membuffer_Malloc,
5610f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek                               (unsigned long) srcBufs.malloc_bytes);
5611ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek  createCXTUResourceUsageEntry(*entries,
5612f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek                               CXTUResourceUsage_SourceManager_Membuffer_MMap,
5613f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek                               (unsigned long) srcBufs.mmap_bytes);
5614ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek  createCXTUResourceUsageEntry(*entries,
5615ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek                               CXTUResourceUsage_SourceManager_DataStructures,
5616ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek                               (unsigned long) astContext.getSourceManager()
5617ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek                                .getDataStructureSizes());
5618e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek
5619e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek  // How much memory is being used by the ExternalASTSource?
5620e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek  if (ExternalASTSource *esrc = astContext.getExternalSource()) {
5621e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek    const ExternalASTSource::MemoryBufferSizes &sizes =
5622e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek      esrc->getMemoryBufferSizes();
5623e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek
5624e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek    createCXTUResourceUsageEntry(*entries,
5625e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek      CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
5626e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek                                 (unsigned long) sizes.malloc_bytes);
5627e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek    createCXTUResourceUsageEntry(*entries,
5628e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek      CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
5629e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek                                 (unsigned long) sizes.mmap_bytes);
5630e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek  }
56315e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek
56325e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek  // How much memory is being used by the Preprocessor?
56335e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek  Preprocessor &pp = astUnit->getPreprocessor();
56345e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek  createCXTUResourceUsageEntry(*entries,
56355e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek                               CXTUResourceUsage_Preprocessor,
5636c5c5e92ec53f7e6ac7ebbbf77c6d8e4b7d88daecArgyrios Kyrtzidis                               pp.getTotalMemory());
56375e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek
56385e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek  if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
56395e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek    createCXTUResourceUsageEntry(*entries,
56405e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek                                 CXTUResourceUsage_PreprocessingRecord,
56415e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek                                 pRec->getTotalMemory());
56425e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek  }
56435e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek
5644d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek  createCXTUResourceUsageEntry(*entries,
5645d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek                               CXTUResourceUsage_Preprocessor_HeaderSearch,
5646d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek                               pp.getHeaderSearchInfo().getTotalMemory());
56475e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek
5648f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek  CXTUResourceUsage usage = { (void*) entries.get(),
564959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek                            (unsigned) entries->size(),
565059fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek                            entries->size() ? &(*entries)[0] : 0 };
565159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  entries.take();
565259fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  return usage;
565359fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek}
565459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
5655f787002478f09af1741fb0f82a562002e6799c49Ted Kremenekvoid clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
565659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek  if (usage.data)
565759fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek    delete (MemUsageEntries*) usage.data;
565859fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek}
565959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
566059fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek} // end extern "C"
566159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
56626df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregorvoid clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
56636df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor  CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
56646df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor  for (unsigned I = 0; I != Usage.numEntries; ++I)
56656df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor    fprintf(stderr, "  %s: %lu\n",
56666df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor            clang_getTUResourceUsageName(Usage.entries[I].kind),
56676df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor            Usage.entries[I].amount);
56686df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor
56696df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor  clang_disposeCXTUResourceUsage(Usage);
56706df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor}
56716df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor
567259fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek//===----------------------------------------------------------------------===//
567304bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek// Misc. utility functions.
567404bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek//===----------------------------------------------------------------------===//
5675f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek
5676abdce7abc8a22dd2fe79a05c0b71864039bd8296Daniel Dunbar/// Default to using an 8 MB stack size on "safety" threads.
5677abdce7abc8a22dd2fe79a05c0b71864039bd8296Daniel Dunbarstatic unsigned SafetyStackThreadSize = 8 << 20;
5678bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar
5679bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarnamespace clang {
5680bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar
5681bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarbool RunSafely(llvm::CrashRecoveryContext &CRC,
56826c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek               void (*Fn)(void*), void *UserData,
56836c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek               unsigned Size) {
56846c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek  if (!Size)
56856c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek    Size = GetSafetyThreadStackSize();
56866c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek  if (Size)
5687bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar    return CRC.RunSafelyOnThread(Fn, UserData, Size);
5688bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar  return CRC.RunSafely(Fn, UserData);
5689bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar}
5690bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar
5691bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarunsigned GetSafetyThreadStackSize() {
5692bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar  return SafetyStackThreadSize;
5693bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar}
5694bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar
5695bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarvoid SetSafetyThreadStackSize(unsigned Value) {
5696bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar  SafetyStackThreadSize = Value;
5697bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar}
5698bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar
5699bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar}
5700bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar
570104bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenekextern "C" {
570204bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek
5703a2a9d6e4e5b6001b86b7dfc5db1ea296ce29a3d3Ted KremenekCXString clang_getClangVersion() {
5704ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek  return createCXString(getClangFullVersion());
570504bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek}
570604bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek
570704bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek} // end: extern "C"
570859fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek
5709