CIndex.cpp revision 74dbe640021d96a8dbb85c592471c04449ade81c
1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===// 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// The LLVM Compiler Infrastructure 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This file is distributed under the University of Illinois Open Source 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// License. See LICENSE.TXT for details. 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This file implements the main API hooks in the Clang-C Source Indexing 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// library. 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "CIndexer.h" 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "CXCursor.h" 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "CXType.h" 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "CXSourceLocation.h" 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "CIndexDiagnostic.h" 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/Version.h" 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/DeclVisitor.h" 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/StmtVisitor.h" 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/TypeLocVisitor.h" 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Basic/Diagnostic.h" 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Frontend/ASTUnit.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Frontend/CompilerInstance.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Frontend/FrontendDiagnostic.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Lex/Lexer.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Lex/PreprocessingRecord.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Lex/Preprocessor.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Support/CrashRecoveryContext.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Support/MemoryBuffer.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Support/Timer.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/System/Program.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/System/Signals.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Needed to define L_TMPNAM on some systems. 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <cstdio> 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace clang; 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace clang::cxcursor; 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace clang::cxstring; 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Crash Reporting. 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef USE_CRASHTRACER 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Analysis/Support/SaveAndRestore.h" 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Integrate with crash reporter. 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const char *__crashreporter_info__ = 0; 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgasm(".desc ___crashreporter_info__, 0x10"); 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define NUM_CRASH_STRINGS 32 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned crashtracer_counter = 0; 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned crashtracer_counter_id[NUM_CRASH_STRINGS] = { 0 }; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const char *crashtracer_strings[NUM_CRASH_STRINGS] = { 0 }; 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const char *agg_crashtracer_strings[NUM_CRASH_STRINGS] = { 0 }; 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned SetCrashTracerInfo(const char *str, 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvm::SmallString<1024> &AggStr) { 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned slot = 0; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (crashtracer_strings[slot]) { 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (++slot == NUM_CRASH_STRINGS) 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org slot = 0; 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org crashtracer_strings[slot] = str; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org crashtracer_counter_id[slot] = ++crashtracer_counter; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // We need to create an aggregate string because multiple threads 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // may be in this method at one time. The crash reporter string 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // will attempt to overapproximate the set of in-flight invocations 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // of this function. Race conditions can still cause this goal 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // to not be achieved. 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvm::raw_svector_ostream Out(AggStr); 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < NUM_CRASH_STRINGS; ++i) 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (crashtracer_strings[i]) Out << crashtracer_strings[i] << '\n'; 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org __crashreporter_info__ = agg_crashtracer_strings[slot] = AggStr.c_str(); 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return slot; 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void ResetCrashTracerInfo(unsigned slot) { 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned max_slot = 0; 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned max_value = 0; 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org crashtracer_strings[slot] = agg_crashtracer_strings[slot] = 0; 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0 ; i < NUM_CRASH_STRINGS; ++i) 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (agg_crashtracer_strings[i] && 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org crashtracer_counter_id[i] > max_value) { 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org max_slot = i; 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org max_value = crashtracer_counter_id[i]; 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org __crashreporter_info__ = agg_crashtracer_strings[max_slot]; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace { 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ArgsCrashTracerInfo { 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvm::SmallString<1024> CrashString; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvm::SmallString<1024> AggregateString; 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned crashtracerSlot; 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ArgsCrashTracerInfo(llvm::SmallVectorImpl<const char*> &Args) 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : crashtracerSlot(0) 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvm::raw_svector_ostream Out(CrashString); 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Out << "ClangCIndex [" << getClangFullVersion() << "]" 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org << "[createTranslationUnitFromSourceFile]: clang"; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (llvm::SmallVectorImpl<const char*>::iterator I=Args.begin(), 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org E=Args.end(); I!=E; ++I) 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Out << ' ' << *I; 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org crashtracerSlot = SetCrashTracerInfo(CrashString.c_str(), 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AggregateString); 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~ArgsCrashTracerInfo() { 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ResetCrashTracerInfo(crashtracerSlot); 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief The result of comparing two source ranges. 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum RangeComparisonResult { 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \brief Either the ranges overlap or one of the ranges is invalid. 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RangeOverlap, 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \brief The first range ends before the second range starts. 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RangeBefore, 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \brief The first range starts after the second range ends. 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RangeAfter 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Compare two source ranges to determine their relative position in 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// the translation unit. 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic RangeComparisonResult RangeCompare(SourceManager &SM, 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SourceRange R1, 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SourceRange R2) { 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(R1.isValid() && "First range is invalid?"); 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(R2.isValid() && "Second range is invalid?"); 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (R1.getEnd() != R2.getBegin() && 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin())) 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return RangeBefore; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (R2.getEnd() != R1.getBegin() && 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin())) 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return RangeAfter; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return RangeOverlap; 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Determine if a source location falls within, before, or after a 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// a given source range. 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic RangeComparisonResult LocationCompare(SourceManager &SM, 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SourceLocation L, SourceRange R) { 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(R.isValid() && "First range is invalid?"); 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(L.isValid() && "Second range is invalid?"); 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (L == R.getBegin() || L == R.getEnd()) 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return RangeOverlap; 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (SM.isBeforeInTranslationUnit(L, R.getBegin())) 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return RangeBefore; 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (SM.isBeforeInTranslationUnit(R.getEnd(), L)) 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return RangeAfter; 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return RangeOverlap; 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Translate a Clang source range into a CIndex source range. 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// Clang internally represents ranges where the end location points to the 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// start of the token at the end. However, for external clients it is more 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// useful to have a CXSourceRange be a proper half-open interval. This routine 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// does the appropriate translation. 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCXSourceRange cxloc::translateSourceRange(const SourceManager &SM, 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const LangOptions &LangOpts, 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const CharSourceRange &R) { 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // We want the last character in this location, so we will adjust the 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // location accordingly. 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // FIXME: How do do this with a macro instantiation location? 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SourceLocation EndLoc = R.getEnd(); 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) { 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts); 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org EndLoc = EndLoc.getFileLocWithOffset(Length); 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts }, 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R.getBegin().getRawEncoding(), 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org EndLoc.getRawEncoding() }; 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Result; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Cursor visitor. 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace { 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Cursor visitor. 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass CursorVisitor : public DeclVisitor<CursorVisitor, bool>, 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org public TypeLocVisitor<CursorVisitor, bool>, 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org public StmtVisitor<CursorVisitor, bool> 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \brief The translation unit we are traversing. 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASTUnit *TU; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \brief The parent cursor whose children we are traversing. 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CXCursor Parent; 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \brief The declaration that serves at the parent of any statement or 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// expression nodes. 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Decl *StmtParent; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \brief The visitor function. 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CXCursorVisitor Visitor; 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \brief The opaque client data, to be passed along to the visitor. 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CXClientData ClientData; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // MaxPCHLevel - the maximum PCH level of declarations that we will pass on 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // to the visitor. Declarations with a PCH level greater than this value will 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // be suppressed. 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned MaxPCHLevel; 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \brief When valid, a source range to which the cursor should restrict 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// its search. 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SourceRange RegionOfInterest; 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org using DeclVisitor<CursorVisitor, bool>::Visit; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org using TypeLocVisitor<CursorVisitor, bool>::Visit; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org using StmtVisitor<CursorVisitor, bool>::Visit; 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \brief Determine whether this particular source range comes before, comes 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// after, or overlaps the region of interest. 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// \param R a half-open source range retrieved from the abstract syntax tree. 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RangeComparisonResult CompareRegionOfInterest(SourceRange R); 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org class SetParentRAII { 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CXCursor &Parent; 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Decl *&StmtParent; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CXCursor OldParent; 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org public: 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent) 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Parent = NewParent; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (clang_isDeclaration(Parent.kind)) 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org StmtParent = getCursorDecl(Parent); 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~SetParentRAII() { 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Parent = OldParent; 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (clang_isDeclaration(Parent.kind)) 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org StmtParent = getCursorDecl(Parent); 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData, 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned MaxPCHLevel, 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SourceRange RegionOfInterest = SourceRange()) 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : TU(TU), Visitor(Visitor), ClientData(ClientData), 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest) 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Parent.kind = CXCursor_NoDeclFound; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Parent.data[0] = 0; 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Parent.data[1] = 0; 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Parent.data[2] = 0; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org StmtParent = 0; 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false); 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org getPreprocessedEntities(); 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitChildren(CXCursor Parent); 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Declaration visitors 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitAttributes(Decl *D); 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitBlockDecl(BlockDecl *B); 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitCXXRecordDecl(CXXRecordDecl *D); 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitDeclContext(DeclContext *DC); 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitTranslationUnitDecl(TranslationUnitDecl *D); 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitTypedefDecl(TypedefDecl *D); 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitTagDecl(TagDecl *D); 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitClassTemplatePartialSpecializationDecl( 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ClassTemplatePartialSpecializationDecl *D); 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitEnumConstantDecl(EnumConstantDecl *D); 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitDeclaratorDecl(DeclaratorDecl *DD); 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitFunctionDecl(FunctionDecl *ND); 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitFieldDecl(FieldDecl *D); 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitVarDecl(VarDecl *); 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D); 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitClassTemplateDecl(ClassTemplateDecl *D); 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCMethodDecl(ObjCMethodDecl *ND); 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCContainerDecl(ObjCContainerDecl *D); 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND); 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID); 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD); 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCImplDecl(ObjCImplDecl *D); 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCImplementationDecl(ObjCImplementationDecl *D); 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // FIXME: ObjCPropertyDecl requires TypeSourceInfo, getter/setter locations, 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // etc. 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations. 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCClassDecl(ObjCClassDecl *D); 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitLinkageSpecDecl(LinkageSpecDecl *D); 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitNamespaceDecl(NamespaceDecl *D); 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Name visitor 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitDeclarationNameInfo(DeclarationNameInfo Name); 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Template visitors 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitTemplateParameters(const TemplateParameterList *Params); 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL); 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Type visitors 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL); 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL); 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitTypedefTypeLoc(TypedefTypeLoc TL); 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL); 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitTagTypeLoc(TagTypeLoc TL); 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL); 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL); 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL); 337 bool VisitPointerTypeLoc(PointerTypeLoc TL); 338 bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL); 339 bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL); 340 bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL); 341 bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL); 342 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false); 343 bool VisitArrayTypeLoc(ArrayTypeLoc TL); 344 bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL); 345 // FIXME: Implement visitors here when the unimplemented TypeLocs get 346 // implemented 347 bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL); 348 bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL); 349 350 // Statement visitors 351 bool VisitStmt(Stmt *S); 352 bool VisitDeclStmt(DeclStmt *S); 353 // FIXME: LabelStmt label? 354 bool VisitIfStmt(IfStmt *S); 355 bool VisitSwitchStmt(SwitchStmt *S); 356 bool VisitCaseStmt(CaseStmt *S); 357 bool VisitWhileStmt(WhileStmt *S); 358 bool VisitForStmt(ForStmt *S); 359// bool VisitSwitchCase(SwitchCase *S); 360 361 // Expression visitors 362 // FIXME: DeclRefExpr with template arguments, nested-name-specifier 363 // FIXME: MemberExpr with template arguments, nested-name-specifier 364 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E); 365 bool VisitBlockExpr(BlockExpr *B); 366 bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E); 367 bool VisitExplicitCastExpr(ExplicitCastExpr *E); 368 bool VisitObjCMessageExpr(ObjCMessageExpr *E); 369 bool VisitObjCEncodeExpr(ObjCEncodeExpr *E); 370 bool VisitOffsetOfExpr(OffsetOfExpr *E); 371 bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); 372 // FIXME: AddrLabelExpr (once we have cursors for labels) 373 bool VisitTypesCompatibleExpr(TypesCompatibleExpr *E); 374 bool VisitVAArgExpr(VAArgExpr *E); 375 // FIXME: InitListExpr (for the designators) 376 // FIXME: DesignatedInitExpr 377}; 378 379} // end anonymous namespace 380 381static SourceRange getRawCursorExtent(CXCursor C); 382 383RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) { 384 return RangeCompare(TU->getSourceManager(), R, RegionOfInterest); 385} 386 387/// \brief Visit the given cursor and, if requested by the visitor, 388/// its children. 389/// 390/// \param Cursor the cursor to visit. 391/// 392/// \param CheckRegionOfInterest if true, then the caller already checked that 393/// this cursor is within the region of interest. 394/// 395/// \returns true if the visitation should be aborted, false if it 396/// should continue. 397bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) { 398 if (clang_isInvalid(Cursor.kind)) 399 return false; 400 401 if (clang_isDeclaration(Cursor.kind)) { 402 Decl *D = getCursorDecl(Cursor); 403 assert(D && "Invalid declaration cursor"); 404 if (D->getPCHLevel() > MaxPCHLevel) 405 return false; 406 407 if (D->isImplicit()) 408 return false; 409 } 410 411 // If we have a range of interest, and this cursor doesn't intersect with it, 412 // we're done. 413 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) { 414 SourceRange Range = getRawCursorExtent(Cursor); 415 if (Range.isInvalid() || CompareRegionOfInterest(Range)) 416 return false; 417 } 418 419 switch (Visitor(Cursor, Parent, ClientData)) { 420 case CXChildVisit_Break: 421 return true; 422 423 case CXChildVisit_Continue: 424 return false; 425 426 case CXChildVisit_Recurse: 427 return VisitChildren(Cursor); 428 } 429 430 return false; 431} 432 433std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> 434CursorVisitor::getPreprocessedEntities() { 435 PreprocessingRecord &PPRec 436 = *TU->getPreprocessor().getPreprocessingRecord(); 437 438 bool OnlyLocalDecls 439 = !TU->isMainFileAST() && TU->getOnlyLocalDecls(); 440 441 // There is no region of interest; we have to walk everything. 442 if (RegionOfInterest.isInvalid()) 443 return std::make_pair(PPRec.begin(OnlyLocalDecls), 444 PPRec.end(OnlyLocalDecls)); 445 446 // Find the file in which the region of interest lands. 447 SourceManager &SM = TU->getSourceManager(); 448 std::pair<FileID, unsigned> Begin 449 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin()); 450 std::pair<FileID, unsigned> End 451 = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd()); 452 453 // The region of interest spans files; we have to walk everything. 454 if (Begin.first != End.first) 455 return std::make_pair(PPRec.begin(OnlyLocalDecls), 456 PPRec.end(OnlyLocalDecls)); 457 458 ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap 459 = TU->getPreprocessedEntitiesByFile(); 460 if (ByFileMap.empty()) { 461 // Build the mapping from files to sets of preprocessed entities. 462 for (PreprocessingRecord::iterator E = PPRec.begin(OnlyLocalDecls), 463 EEnd = PPRec.end(OnlyLocalDecls); 464 E != EEnd; ++E) { 465 std::pair<FileID, unsigned> P 466 = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin()); 467 ByFileMap[P.first].push_back(*E); 468 } 469 } 470 471 return std::make_pair(ByFileMap[Begin.first].begin(), 472 ByFileMap[Begin.first].end()); 473} 474 475/// \brief Visit the children of the given cursor. 476/// 477/// \returns true if the visitation should be aborted, false if it 478/// should continue. 479bool CursorVisitor::VisitChildren(CXCursor Cursor) { 480 if (clang_isReference(Cursor.kind)) { 481 // By definition, references have no children. 482 return false; 483 } 484 485 // Set the Parent field to Cursor, then back to its old value once we're 486 // done. 487 SetParentRAII SetParent(Parent, StmtParent, Cursor); 488 489 if (clang_isDeclaration(Cursor.kind)) { 490 Decl *D = getCursorDecl(Cursor); 491 assert(D && "Invalid declaration cursor"); 492 return VisitAttributes(D) || Visit(D); 493 } 494 495 if (clang_isStatement(Cursor.kind)) 496 return Visit(getCursorStmt(Cursor)); 497 if (clang_isExpression(Cursor.kind)) 498 return Visit(getCursorExpr(Cursor)); 499 500 if (clang_isTranslationUnit(Cursor.kind)) { 501 ASTUnit *CXXUnit = getCursorASTUnit(Cursor); 502 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() && 503 RegionOfInterest.isInvalid()) { 504 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(), 505 TLEnd = CXXUnit->top_level_end(); 506 TL != TLEnd; ++TL) { 507 if (Visit(MakeCXCursor(*TL, CXXUnit), true)) 508 return true; 509 } 510 } else if (VisitDeclContext( 511 CXXUnit->getASTContext().getTranslationUnitDecl())) 512 return true; 513 514 // Walk the preprocessing record. 515 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) { 516 // FIXME: Once we have the ability to deserialize a preprocessing record, 517 // do so. 518 PreprocessingRecord::iterator E, EEnd; 519 for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) { 520 if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { 521 if (Visit(MakeMacroInstantiationCursor(MI, CXXUnit))) 522 return true; 523 524 continue; 525 } 526 527 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { 528 if (Visit(MakeMacroDefinitionCursor(MD, CXXUnit))) 529 return true; 530 531 continue; 532 } 533 } 534 } 535 return false; 536 } 537 538 // Nothing to visit at the moment. 539 return false; 540} 541 542bool CursorVisitor::VisitBlockDecl(BlockDecl *B) { 543 if (Visit(B->getSignatureAsWritten()->getTypeLoc())) 544 return true; 545 546 if (Stmt *Body = B->getBody()) 547 return Visit(MakeCXCursor(Body, StmtParent, TU)); 548 549 return false; 550} 551 552bool CursorVisitor::VisitDeclContext(DeclContext *DC) { 553 for (DeclContext::decl_iterator 554 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { 555 556 Decl *D = *I; 557 if (D->getLexicalDeclContext() != DC) 558 continue; 559 560 CXCursor Cursor = MakeCXCursor(D, TU); 561 562 if (RegionOfInterest.isValid()) { 563 SourceRange Range = getRawCursorExtent(Cursor); 564 if (Range.isInvalid()) 565 continue; 566 567 switch (CompareRegionOfInterest(Range)) { 568 case RangeBefore: 569 // This declaration comes before the region of interest; skip it. 570 continue; 571 572 case RangeAfter: 573 // This declaration comes after the region of interest; we're done. 574 return false; 575 576 case RangeOverlap: 577 // This declaration overlaps the region of interest; visit it. 578 break; 579 } 580 } 581 582 if (Visit(Cursor, true)) 583 return true; 584 } 585 586 return false; 587} 588 589bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) { 590 llvm_unreachable("Translation units are visited directly by Visit()"); 591 return false; 592} 593 594bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) { 595 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo()) 596 return Visit(TSInfo->getTypeLoc()); 597 598 return false; 599} 600 601bool CursorVisitor::VisitTagDecl(TagDecl *D) { 602 return VisitDeclContext(D); 603} 604 605bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl( 606 ClassTemplatePartialSpecializationDecl *D) { 607 // FIXME: Visit the "outer" template parameter lists on the TagDecl 608 // before visiting these template parameters. 609 if (VisitTemplateParameters(D->getTemplateParameters())) 610 return true; 611 612 // Visit the partial specialization arguments. 613 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten(); 614 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I) 615 if (VisitTemplateArgumentLoc(TemplateArgs[I])) 616 return true; 617 618 return VisitCXXRecordDecl(D); 619} 620 621bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { 622 // FIXME: Visit default argument 623 return false; 624} 625 626bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) { 627 if (Expr *Init = D->getInitExpr()) 628 return Visit(MakeCXCursor(Init, StmtParent, TU)); 629 return false; 630} 631 632bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { 633 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo()) 634 if (Visit(TSInfo->getTypeLoc())) 635 return true; 636 637 return false; 638} 639 640bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { 641 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) { 642 // Visit the function declaration's syntactic components in the order 643 // written. This requires a bit of work. 644 TypeLoc TL = TSInfo->getTypeLoc(); 645 FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL); 646 647 // If we have a function declared directly (without the use of a typedef), 648 // visit just the return type. Otherwise, just visit the function's type 649 // now. 650 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) || 651 (!FTL && Visit(TL))) 652 return true; 653 654 // FIXME: Visit the nested-name-specifier, if present. 655 656 // Visit the declaration name. 657 if (VisitDeclarationNameInfo(ND->getNameInfo())) 658 return true; 659 660 // FIXME: Visit explicitly-specified template arguments! 661 662 // Visit the function parameters, if we have a function type. 663 if (FTL && VisitFunctionTypeLoc(*FTL, true)) 664 return true; 665 666 // FIXME: Attributes? 667 } 668 669 if (ND->isThisDeclarationADefinition() && 670 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) 671 return true; 672 673 return false; 674} 675 676bool CursorVisitor::VisitFieldDecl(FieldDecl *D) { 677 if (VisitDeclaratorDecl(D)) 678 return true; 679 680 if (Expr *BitWidth = D->getBitWidth()) 681 return Visit(MakeCXCursor(BitWidth, StmtParent, TU)); 682 683 return false; 684} 685 686bool CursorVisitor::VisitVarDecl(VarDecl *D) { 687 if (VisitDeclaratorDecl(D)) 688 return true; 689 690 if (Expr *Init = D->getInit()) 691 return Visit(MakeCXCursor(Init, StmtParent, TU)); 692 693 return false; 694} 695 696bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { 697 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl 698 // before visiting these template parameters. 699 if (VisitTemplateParameters(D->getTemplateParameters())) 700 return true; 701 702 return VisitFunctionDecl(D->getTemplatedDecl()); 703} 704 705bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { 706 // FIXME: Visit the "outer" template parameter lists on the TagDecl 707 // before visiting these template parameters. 708 if (VisitTemplateParameters(D->getTemplateParameters())) 709 return true; 710 711 return VisitCXXRecordDecl(D->getTemplatedDecl()); 712} 713 714bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) { 715 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo()) 716 if (Visit(TSInfo->getTypeLoc())) 717 return true; 718 719 for (ObjCMethodDecl::param_iterator P = ND->param_begin(), 720 PEnd = ND->param_end(); 721 P != PEnd; ++P) { 722 if (Visit(MakeCXCursor(*P, TU))) 723 return true; 724 } 725 726 if (ND->isThisDeclarationADefinition() && 727 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) 728 return true; 729 730 return false; 731} 732 733bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { 734 return VisitDeclContext(D); 735} 736 737bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { 738 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(), 739 TU))) 740 return true; 741 742 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin(); 743 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(), 744 E = ND->protocol_end(); I != E; ++I, ++PL) 745 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 746 return true; 747 748 return VisitObjCContainerDecl(ND); 749} 750 751bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { 752 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin(); 753 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), 754 E = PID->protocol_end(); I != E; ++I, ++PL) 755 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 756 return true; 757 758 return VisitObjCContainerDecl(PID); 759} 760 761bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) { 762 if (Visit(PD->getTypeSourceInfo()->getTypeLoc())) 763 return true; 764 765 // FIXME: This implements a workaround with @property declarations also being 766 // installed in the DeclContext for the @interface. Eventually this code 767 // should be removed. 768 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext()); 769 if (!CDecl || !CDecl->IsClassExtension()) 770 return false; 771 772 ObjCInterfaceDecl *ID = CDecl->getClassInterface(); 773 if (!ID) 774 return false; 775 776 IdentifierInfo *PropertyId = PD->getIdentifier(); 777 ObjCPropertyDecl *prevDecl = 778 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId); 779 780 if (!prevDecl) 781 return false; 782 783 // Visit synthesized methods since they will be skipped when visiting 784 // the @interface. 785 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl()) 786 if (MD->isSynthesized()) 787 if (Visit(MakeCXCursor(MD, TU))) 788 return true; 789 790 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl()) 791 if (MD->isSynthesized()) 792 if (Visit(MakeCXCursor(MD, TU))) 793 return true; 794 795 return false; 796} 797 798bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { 799 // Issue callbacks for super class. 800 if (D->getSuperClass() && 801 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), 802 D->getSuperClassLoc(), 803 TU))) 804 return true; 805 806 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); 807 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), 808 E = D->protocol_end(); I != E; ++I, ++PL) 809 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 810 return true; 811 812 return VisitObjCContainerDecl(D); 813} 814 815bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) { 816 return VisitObjCContainerDecl(D); 817} 818 819bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { 820 // 'ID' could be null when dealing with invalid code. 821 if (ObjCInterfaceDecl *ID = D->getClassInterface()) 822 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU))) 823 return true; 824 825 return VisitObjCImplDecl(D); 826} 827 828bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { 829#if 0 830 // Issue callbacks for super class. 831 // FIXME: No source location information! 832 if (D->getSuperClass() && 833 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), 834 D->getSuperClassLoc(), 835 TU))) 836 return true; 837#endif 838 839 return VisitObjCImplDecl(D); 840} 841 842bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { 843 ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); 844 for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(), 845 E = D->protocol_end(); 846 I != E; ++I, ++PL) 847 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 848 return true; 849 850 return false; 851} 852 853bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) { 854 for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C) 855 if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU))) 856 return true; 857 858 return false; 859} 860 861bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) { 862 return VisitDeclContext(D); 863} 864 865bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) { 866 switch (Name.getName().getNameKind()) { 867 case clang::DeclarationName::Identifier: 868 case clang::DeclarationName::CXXLiteralOperatorName: 869 case clang::DeclarationName::CXXOperatorName: 870 case clang::DeclarationName::CXXUsingDirective: 871 return false; 872 873 case clang::DeclarationName::CXXConstructorName: 874 case clang::DeclarationName::CXXDestructorName: 875 case clang::DeclarationName::CXXConversionFunctionName: 876 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo()) 877 return Visit(TSInfo->getTypeLoc()); 878 return false; 879 880 case clang::DeclarationName::ObjCZeroArgSelector: 881 case clang::DeclarationName::ObjCOneArgSelector: 882 case clang::DeclarationName::ObjCMultiArgSelector: 883 // FIXME: Per-identifier location info? 884 return false; 885 } 886 887 return false; 888} 889 890bool CursorVisitor::VisitTemplateParameters( 891 const TemplateParameterList *Params) { 892 if (!Params) 893 return false; 894 895 for (TemplateParameterList::const_iterator P = Params->begin(), 896 PEnd = Params->end(); 897 P != PEnd; ++P) { 898 if (Visit(MakeCXCursor(*P, TU))) 899 return true; 900 } 901 902 return false; 903} 904 905bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) { 906 switch (TAL.getArgument().getKind()) { 907 case TemplateArgument::Null: 908 case TemplateArgument::Integral: 909 return false; 910 911 case TemplateArgument::Pack: 912 // FIXME: Implement when variadic templates come along. 913 return false; 914 915 case TemplateArgument::Type: 916 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo()) 917 return Visit(TSInfo->getTypeLoc()); 918 return false; 919 920 case TemplateArgument::Declaration: 921 if (Expr *E = TAL.getSourceDeclExpression()) 922 return Visit(MakeCXCursor(E, StmtParent, TU)); 923 return false; 924 925 case TemplateArgument::Expression: 926 if (Expr *E = TAL.getSourceExpression()) 927 return Visit(MakeCXCursor(E, StmtParent, TU)); 928 return false; 929 930 case TemplateArgument::Template: 931 // FIXME: Visit template name. 932 return false; 933 } 934 935 return false; 936} 937 938bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) { 939 return VisitDeclContext(D); 940} 941 942bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { 943 return Visit(TL.getUnqualifiedLoc()); 944} 945 946bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { 947 ASTContext &Context = TU->getASTContext(); 948 949 // Some builtin types (such as Objective-C's "id", "sel", and 950 // "Class") have associated declarations. Create cursors for those. 951 QualType VisitType; 952 switch (TL.getType()->getAs<BuiltinType>()->getKind()) { 953 case BuiltinType::Void: 954 case BuiltinType::Bool: 955 case BuiltinType::Char_U: 956 case BuiltinType::UChar: 957 case BuiltinType::Char16: 958 case BuiltinType::Char32: 959 case BuiltinType::UShort: 960 case BuiltinType::UInt: 961 case BuiltinType::ULong: 962 case BuiltinType::ULongLong: 963 case BuiltinType::UInt128: 964 case BuiltinType::Char_S: 965 case BuiltinType::SChar: 966 case BuiltinType::WChar: 967 case BuiltinType::Short: 968 case BuiltinType::Int: 969 case BuiltinType::Long: 970 case BuiltinType::LongLong: 971 case BuiltinType::Int128: 972 case BuiltinType::Float: 973 case BuiltinType::Double: 974 case BuiltinType::LongDouble: 975 case BuiltinType::NullPtr: 976 case BuiltinType::Overload: 977 case BuiltinType::Dependent: 978 break; 979 980 case BuiltinType::UndeducedAuto: // FIXME: Deserves a cursor? 981 break; 982 983 case BuiltinType::ObjCId: 984 VisitType = Context.getObjCIdType(); 985 break; 986 987 case BuiltinType::ObjCClass: 988 VisitType = Context.getObjCClassType(); 989 break; 990 991 case BuiltinType::ObjCSel: 992 VisitType = Context.getObjCSelType(); 993 break; 994 } 995 996 if (!VisitType.isNull()) { 997 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>()) 998 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), 999 TU)); 1000 } 1001 1002 return false; 1003} 1004 1005bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) { 1006 return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU)); 1007} 1008 1009bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { 1010 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 1011} 1012 1013bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) { 1014 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 1015} 1016 1017bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { 1018 // FIXME: We can't visit the template template parameter, but there's 1019 // no context information with which we can match up the depth/index in the 1020 // type to the appropriate 1021 return false; 1022} 1023 1024bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 1025 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU))) 1026 return true; 1027 1028 return false; 1029} 1030 1031bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 1032 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc())) 1033 return true; 1034 1035 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { 1036 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I), 1037 TU))) 1038 return true; 1039 } 1040 1041 return false; 1042} 1043 1044bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { 1045 return Visit(TL.getPointeeLoc()); 1046} 1047 1048bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) { 1049 return Visit(TL.getPointeeLoc()); 1050} 1051 1052bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { 1053 return Visit(TL.getPointeeLoc()); 1054} 1055 1056bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 1057 return Visit(TL.getPointeeLoc()); 1058} 1059 1060bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { 1061 return Visit(TL.getPointeeLoc()); 1062} 1063 1064bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { 1065 return Visit(TL.getPointeeLoc()); 1066} 1067 1068bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL, 1069 bool SkipResultType) { 1070 if (!SkipResultType && Visit(TL.getResultLoc())) 1071 return true; 1072 1073 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 1074 if (Decl *D = TL.getArg(I)) 1075 if (Visit(MakeCXCursor(D, TU))) 1076 return true; 1077 1078 return false; 1079} 1080 1081bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) { 1082 if (Visit(TL.getElementLoc())) 1083 return true; 1084 1085 if (Expr *Size = TL.getSizeExpr()) 1086 return Visit(MakeCXCursor(Size, StmtParent, TU)); 1087 1088 return false; 1089} 1090 1091bool CursorVisitor::VisitTemplateSpecializationTypeLoc( 1092 TemplateSpecializationTypeLoc TL) { 1093 // FIXME: Visit the template name. 1094 1095 // Visit the template arguments. 1096 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 1097 if (VisitTemplateArgumentLoc(TL.getArgLoc(I))) 1098 return true; 1099 1100 return false; 1101} 1102 1103bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 1104 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU)); 1105} 1106 1107bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { 1108 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo()) 1109 return Visit(TSInfo->getTypeLoc()); 1110 1111 return false; 1112} 1113 1114bool CursorVisitor::VisitStmt(Stmt *S) { 1115 for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end(); 1116 Child != ChildEnd; ++Child) { 1117 if (Stmt *C = *Child) 1118 if (Visit(MakeCXCursor(C, StmtParent, TU))) 1119 return true; 1120 } 1121 1122 return false; 1123} 1124 1125bool CursorVisitor::VisitCaseStmt(CaseStmt *S) { 1126 // Specially handle CaseStmts because they can be nested, e.g.: 1127 // 1128 // case 1: 1129 // case 2: 1130 // 1131 // In this case the second CaseStmt is the child of the first. Walking 1132 // these recursively can blow out the stack. 1133 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU); 1134 while (true) { 1135 // Set the Parent field to Cursor, then back to its old value once we're 1136 // done. 1137 SetParentRAII SetParent(Parent, StmtParent, Cursor); 1138 1139 if (Stmt *LHS = S->getLHS()) 1140 if (Visit(MakeCXCursor(LHS, StmtParent, TU))) 1141 return true; 1142 if (Stmt *RHS = S->getRHS()) 1143 if (Visit(MakeCXCursor(RHS, StmtParent, TU))) 1144 return true; 1145 if (Stmt *SubStmt = S->getSubStmt()) { 1146 if (!isa<CaseStmt>(SubStmt)) 1147 return Visit(MakeCXCursor(SubStmt, StmtParent, TU)); 1148 1149 // Specially handle 'CaseStmt' so that we don't blow out the stack. 1150 CaseStmt *CS = cast<CaseStmt>(SubStmt); 1151 Cursor = MakeCXCursor(CS, StmtParent, TU); 1152 if (RegionOfInterest.isValid()) { 1153 SourceRange Range = CS->getSourceRange(); 1154 if (Range.isInvalid() || CompareRegionOfInterest(Range)) 1155 return false; 1156 } 1157 1158 switch (Visitor(Cursor, Parent, ClientData)) { 1159 case CXChildVisit_Break: return true; 1160 case CXChildVisit_Continue: return false; 1161 case CXChildVisit_Recurse: 1162 // Perform tail-recursion manually. 1163 S = CS; 1164 continue; 1165 } 1166 } 1167 return false; 1168 } 1169} 1170 1171bool CursorVisitor::VisitDeclStmt(DeclStmt *S) { 1172 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); 1173 D != DEnd; ++D) { 1174 if (*D && Visit(MakeCXCursor(*D, TU))) 1175 return true; 1176 } 1177 1178 return false; 1179} 1180 1181bool CursorVisitor::VisitIfStmt(IfStmt *S) { 1182 if (VarDecl *Var = S->getConditionVariable()) { 1183 if (Visit(MakeCXCursor(Var, TU))) 1184 return true; 1185 } 1186 1187 if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) 1188 return true; 1189 if (S->getThen() && Visit(MakeCXCursor(S->getThen(), StmtParent, TU))) 1190 return true; 1191 if (S->getElse() && Visit(MakeCXCursor(S->getElse(), StmtParent, TU))) 1192 return true; 1193 1194 return false; 1195} 1196 1197bool CursorVisitor::VisitSwitchStmt(SwitchStmt *S) { 1198 if (VarDecl *Var = S->getConditionVariable()) { 1199 if (Visit(MakeCXCursor(Var, TU))) 1200 return true; 1201 } 1202 1203 if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) 1204 return true; 1205 if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) 1206 return true; 1207 1208 return false; 1209} 1210 1211bool CursorVisitor::VisitWhileStmt(WhileStmt *S) { 1212 if (VarDecl *Var = S->getConditionVariable()) { 1213 if (Visit(MakeCXCursor(Var, TU))) 1214 return true; 1215 } 1216 1217 if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) 1218 return true; 1219 if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) 1220 return true; 1221 1222 return false; 1223} 1224 1225bool CursorVisitor::VisitForStmt(ForStmt *S) { 1226 if (S->getInit() && Visit(MakeCXCursor(S->getInit(), StmtParent, TU))) 1227 return true; 1228 if (VarDecl *Var = S->getConditionVariable()) { 1229 if (Visit(MakeCXCursor(Var, TU))) 1230 return true; 1231 } 1232 1233 if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) 1234 return true; 1235 if (S->getInc() && Visit(MakeCXCursor(S->getInc(), StmtParent, TU))) 1236 return true; 1237 if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) 1238 return true; 1239 1240 return false; 1241} 1242 1243bool CursorVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { 1244 if (Visit(MakeCXCursor(E->getArg(0), StmtParent, TU))) 1245 return true; 1246 1247 if (Visit(MakeCXCursor(E->getCallee(), StmtParent, TU))) 1248 return true; 1249 1250 for (unsigned I = 1, N = E->getNumArgs(); I != N; ++I) 1251 if (Visit(MakeCXCursor(E->getArg(I), StmtParent, TU))) 1252 return true; 1253 1254 return false; 1255} 1256 1257bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) { 1258 if (D->isDefinition()) { 1259 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), 1260 E = D->bases_end(); I != E; ++I) { 1261 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU))) 1262 return true; 1263 } 1264 } 1265 1266 return VisitTagDecl(D); 1267} 1268 1269 1270bool CursorVisitor::VisitBlockExpr(BlockExpr *B) { 1271 return Visit(B->getBlockDecl()); 1272} 1273 1274bool CursorVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) { 1275 // FIXME: Visit fields as well? 1276 if (Visit(E->getTypeSourceInfo()->getTypeLoc())) 1277 return true; 1278 1279 return VisitExpr(E); 1280} 1281 1282bool CursorVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { 1283 if (E->isArgumentType()) { 1284 if (TypeSourceInfo *TSInfo = E->getArgumentTypeInfo()) 1285 return Visit(TSInfo->getTypeLoc()); 1286 1287 return false; 1288 } 1289 1290 return VisitExpr(E); 1291} 1292 1293bool CursorVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) { 1294 if (TypeSourceInfo *TSInfo = E->getTypeInfoAsWritten()) 1295 if (Visit(TSInfo->getTypeLoc())) 1296 return true; 1297 1298 return VisitCastExpr(E); 1299} 1300 1301bool CursorVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 1302 if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) 1303 if (Visit(TSInfo->getTypeLoc())) 1304 return true; 1305 1306 return VisitExpr(E); 1307} 1308 1309bool CursorVisitor::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) { 1310 return Visit(E->getArgTInfo1()->getTypeLoc()) || 1311 Visit(E->getArgTInfo2()->getTypeLoc()); 1312} 1313 1314bool CursorVisitor::VisitVAArgExpr(VAArgExpr *E) { 1315 if (Visit(E->getWrittenTypeInfo()->getTypeLoc())) 1316 return true; 1317 1318 return Visit(MakeCXCursor(E->getSubExpr(), StmtParent, TU)); 1319} 1320 1321bool CursorVisitor::VisitObjCMessageExpr(ObjCMessageExpr *E) { 1322 if (TypeSourceInfo *TSInfo = E->getClassReceiverTypeInfo()) 1323 if (Visit(TSInfo->getTypeLoc())) 1324 return true; 1325 1326 return VisitExpr(E); 1327} 1328 1329bool CursorVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { 1330 return Visit(E->getEncodedTypeSourceInfo()->getTypeLoc()); 1331} 1332 1333 1334bool CursorVisitor::VisitAttributes(Decl *D) { 1335 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end(); 1336 i != e; ++i) 1337 if (Visit(MakeCXCursor(*i, D, TU))) 1338 return true; 1339 1340 return false; 1341} 1342 1343extern "C" { 1344CXIndex clang_createIndex(int excludeDeclarationsFromPCH, 1345 int displayDiagnostics) { 1346 // We use crash recovery to make some of our APIs more reliable, implicitly 1347 // enable it. 1348 llvm::CrashRecoveryContext::Enable(); 1349 1350 CIndexer *CIdxr = new CIndexer(); 1351 if (excludeDeclarationsFromPCH) 1352 CIdxr->setOnlyLocalDecls(); 1353 if (displayDiagnostics) 1354 CIdxr->setDisplayDiagnostics(); 1355 return CIdxr; 1356} 1357 1358void clang_disposeIndex(CXIndex CIdx) { 1359 if (CIdx) 1360 delete static_cast<CIndexer *>(CIdx); 1361 if (getenv("LIBCLANG_TIMING")) 1362 llvm::TimerGroup::printAll(llvm::errs()); 1363} 1364 1365void clang_setUseExternalASTGeneration(CXIndex CIdx, int value) { 1366 if (CIdx) { 1367 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 1368 CXXIdx->setUseExternalASTGeneration(value); 1369 } 1370} 1371 1372CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, 1373 const char *ast_filename) { 1374 if (!CIdx) 1375 return 0; 1376 1377 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 1378 1379 llvm::IntrusiveRefCntPtr<Diagnostic> Diags; 1380 return ASTUnit::LoadFromASTFile(ast_filename, Diags, 1381 CXXIdx->getOnlyLocalDecls(), 1382 0, 0, true); 1383} 1384 1385unsigned clang_defaultEditingTranslationUnitOptions() { 1386 return CXTranslationUnit_PrecompiledPreamble; 1387} 1388 1389CXTranslationUnit 1390clang_createTranslationUnitFromSourceFile(CXIndex CIdx, 1391 const char *source_filename, 1392 int num_command_line_args, 1393 const char **command_line_args, 1394 unsigned num_unsaved_files, 1395 struct CXUnsavedFile *unsaved_files) { 1396 return clang_parseTranslationUnit(CIdx, source_filename, 1397 command_line_args, num_command_line_args, 1398 unsaved_files, num_unsaved_files, 1399 CXTranslationUnit_DetailedPreprocessingRecord); 1400} 1401 1402struct ParseTranslationUnitInfo { 1403 CXIndex CIdx; 1404 const char *source_filename; 1405 const char **command_line_args; 1406 int num_command_line_args; 1407 struct CXUnsavedFile *unsaved_files; 1408 unsigned num_unsaved_files; 1409 unsigned options; 1410 CXTranslationUnit result; 1411}; 1412static void clang_parseTranslationUnit_Impl(void *UserData) { 1413 ParseTranslationUnitInfo *PTUI = 1414 static_cast<ParseTranslationUnitInfo*>(UserData); 1415 CXIndex CIdx = PTUI->CIdx; 1416 const char *source_filename = PTUI->source_filename; 1417 const char **command_line_args = PTUI->command_line_args; 1418 int num_command_line_args = PTUI->num_command_line_args; 1419 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files; 1420 unsigned num_unsaved_files = PTUI->num_unsaved_files; 1421 unsigned options = PTUI->options; 1422 PTUI->result = 0; 1423 1424 if (!CIdx) 1425 return; 1426 1427 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 1428 1429 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble; 1430 bool CompleteTranslationUnit 1431 = ((options & CXTranslationUnit_Incomplete) == 0); 1432 bool CacheCodeCompetionResults 1433 = options & CXTranslationUnit_CacheCompletionResults; 1434 1435 // Configure the diagnostics. 1436 DiagnosticOptions DiagOpts; 1437 llvm::IntrusiveRefCntPtr<Diagnostic> Diags; 1438 Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); 1439 1440 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; 1441 for (unsigned I = 0; I != num_unsaved_files; ++I) { 1442 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); 1443 const llvm::MemoryBuffer *Buffer 1444 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); 1445 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, 1446 Buffer)); 1447 } 1448 1449 if (!CXXIdx->getUseExternalASTGeneration()) { 1450 llvm::SmallVector<const char *, 16> Args; 1451 1452 // The 'source_filename' argument is optional. If the caller does not 1453 // specify it then it is assumed that the source file is specified 1454 // in the actual argument list. 1455 if (source_filename) 1456 Args.push_back(source_filename); 1457 1458 // Since the Clang C library is primarily used by batch tools dealing with 1459 // (often very broken) source code, where spell-checking can have a 1460 // significant negative impact on performance (particularly when 1461 // precompiled headers are involved), we disable it by default. 1462 // Note that we place this argument early in the list, so that it can be 1463 // overridden by the caller with "-fspell-checking". 1464 Args.push_back("-fno-spell-checking"); 1465 1466 Args.insert(Args.end(), command_line_args, 1467 command_line_args + num_command_line_args); 1468 1469 // Do we need the detailed preprocessing record? 1470 if (options & CXTranslationUnit_DetailedPreprocessingRecord) { 1471 Args.push_back("-Xclang"); 1472 Args.push_back("-detailed-preprocessing-record"); 1473 } 1474 1475 unsigned NumErrors = Diags->getNumErrors(); 1476 1477#ifdef USE_CRASHTRACER 1478 ArgsCrashTracerInfo ACTI(Args); 1479#endif 1480 1481 llvm::OwningPtr<ASTUnit> Unit( 1482 ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(), 1483 Diags, 1484 CXXIdx->getClangResourcesPath(), 1485 CXXIdx->getOnlyLocalDecls(), 1486 RemappedFiles.data(), 1487 RemappedFiles.size(), 1488 /*CaptureDiagnostics=*/true, 1489 PrecompilePreamble, 1490 CompleteTranslationUnit, 1491 CacheCodeCompetionResults)); 1492 1493 if (NumErrors != Diags->getNumErrors()) { 1494 // Make sure to check that 'Unit' is non-NULL. 1495 if (CXXIdx->getDisplayDiagnostics() && Unit.get()) { 1496 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), 1497 DEnd = Unit->stored_diag_end(); 1498 D != DEnd; ++D) { 1499 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions()); 1500 CXString Msg = clang_formatDiagnostic(&Diag, 1501 clang_defaultDiagnosticDisplayOptions()); 1502 fprintf(stderr, "%s\n", clang_getCString(Msg)); 1503 clang_disposeString(Msg); 1504 } 1505#ifdef LLVM_ON_WIN32 1506 // On Windows, force a flush, since there may be multiple copies of 1507 // stderr and stdout in the file system, all with different buffers 1508 // but writing to the same device. 1509 fflush(stderr); 1510#endif 1511 } 1512 } 1513 1514 PTUI->result = Unit.take(); 1515 return; 1516 } 1517 1518 // Build up the arguments for invoking 'clang'. 1519 std::vector<const char *> argv; 1520 1521 // First add the complete path to the 'clang' executable. 1522 llvm::sys::Path ClangPath = static_cast<CIndexer *>(CIdx)->getClangPath(); 1523 argv.push_back(ClangPath.c_str()); 1524 1525 // Add the '-emit-ast' option as our execution mode for 'clang'. 1526 argv.push_back("-emit-ast"); 1527 1528 // The 'source_filename' argument is optional. If the caller does not 1529 // specify it then it is assumed that the source file is specified 1530 // in the actual argument list. 1531 if (source_filename) 1532 argv.push_back(source_filename); 1533 1534 // Generate a temporary name for the AST file. 1535 argv.push_back("-o"); 1536 char astTmpFile[L_tmpnam]; 1537 argv.push_back(tmpnam(astTmpFile)); 1538 1539 // Since the Clang C library is primarily used by batch tools dealing with 1540 // (often very broken) source code, where spell-checking can have a 1541 // significant negative impact on performance (particularly when 1542 // precompiled headers are involved), we disable it by default. 1543 // Note that we place this argument early in the list, so that it can be 1544 // overridden by the caller with "-fspell-checking". 1545 argv.push_back("-fno-spell-checking"); 1546 1547 // Remap any unsaved files to temporary files. 1548 std::vector<llvm::sys::Path> TemporaryFiles; 1549 std::vector<std::string> RemapArgs; 1550 if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles)) 1551 return; 1552 1553 // The pointers into the elements of RemapArgs are stable because we 1554 // won't be adding anything to RemapArgs after this point. 1555 for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i) 1556 argv.push_back(RemapArgs[i].c_str()); 1557 1558 // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'. 1559 for (int i = 0; i < num_command_line_args; ++i) 1560 if (const char *arg = command_line_args[i]) { 1561 if (strcmp(arg, "-o") == 0) { 1562 ++i; // Also skip the matching argument. 1563 continue; 1564 } 1565 if (strcmp(arg, "-emit-ast") == 0 || 1566 strcmp(arg, "-c") == 0 || 1567 strcmp(arg, "-fsyntax-only") == 0) { 1568 continue; 1569 } 1570 1571 // Keep the argument. 1572 argv.push_back(arg); 1573 } 1574 1575 // Generate a temporary name for the diagnostics file. 1576 char tmpFileResults[L_tmpnam]; 1577 char *tmpResultsFileName = tmpnam(tmpFileResults); 1578 llvm::sys::Path DiagnosticsFile(tmpResultsFileName); 1579 TemporaryFiles.push_back(DiagnosticsFile); 1580 argv.push_back("-fdiagnostics-binary"); 1581 1582 // Do we need the detailed preprocessing record? 1583 if (options & CXTranslationUnit_DetailedPreprocessingRecord) { 1584 argv.push_back("-Xclang"); 1585 argv.push_back("-detailed-preprocessing-record"); 1586 } 1587 1588 // Add the null terminator. 1589 argv.push_back(NULL); 1590 1591 // Invoke 'clang'. 1592 llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null 1593 // on Unix or NUL (Windows). 1594 std::string ErrMsg; 1595 const llvm::sys::Path *Redirects[] = { &DevNull, &DevNull, &DiagnosticsFile, 1596 NULL }; 1597 llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL, 1598 /* redirects */ &Redirects[0], 1599 /* secondsToWait */ 0, /* memoryLimits */ 0, &ErrMsg); 1600 1601 if (!ErrMsg.empty()) { 1602 std::string AllArgs; 1603 for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end(); 1604 I != E; ++I) { 1605 AllArgs += ' '; 1606 if (*I) 1607 AllArgs += *I; 1608 } 1609 1610 Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg; 1611 } 1612 1613 ASTUnit *ATU = ASTUnit::LoadFromASTFile(astTmpFile, Diags, 1614 CXXIdx->getOnlyLocalDecls(), 1615 RemappedFiles.data(), 1616 RemappedFiles.size(), 1617 /*CaptureDiagnostics=*/true); 1618 if (ATU) { 1619 LoadSerializedDiagnostics(DiagnosticsFile, 1620 num_unsaved_files, unsaved_files, 1621 ATU->getFileManager(), 1622 ATU->getSourceManager(), 1623 ATU->getStoredDiagnostics()); 1624 } else if (CXXIdx->getDisplayDiagnostics()) { 1625 // We failed to load the ASTUnit, but we can still deserialize the 1626 // diagnostics and emit them. 1627 FileManager FileMgr; 1628 Diagnostic Diag; 1629 SourceManager SourceMgr(Diag); 1630 // FIXME: Faked LangOpts! 1631 LangOptions LangOpts; 1632 llvm::SmallVector<StoredDiagnostic, 4> Diags; 1633 LoadSerializedDiagnostics(DiagnosticsFile, 1634 num_unsaved_files, unsaved_files, 1635 FileMgr, SourceMgr, Diags); 1636 for (llvm::SmallVector<StoredDiagnostic, 4>::iterator D = Diags.begin(), 1637 DEnd = Diags.end(); 1638 D != DEnd; ++D) { 1639 CXStoredDiagnostic Diag(*D, LangOpts); 1640 CXString Msg = clang_formatDiagnostic(&Diag, 1641 clang_defaultDiagnosticDisplayOptions()); 1642 fprintf(stderr, "%s\n", clang_getCString(Msg)); 1643 clang_disposeString(Msg); 1644 } 1645 1646#ifdef LLVM_ON_WIN32 1647 // On Windows, force a flush, since there may be multiple copies of 1648 // stderr and stdout in the file system, all with different buffers 1649 // but writing to the same device. 1650 fflush(stderr); 1651#endif 1652 } 1653 1654 if (ATU) { 1655 // Make the translation unit responsible for destroying all temporary files. 1656 for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) 1657 ATU->addTemporaryFile(TemporaryFiles[i]); 1658 ATU->addTemporaryFile(llvm::sys::Path(ATU->getASTFileName())); 1659 } else { 1660 // Destroy all of the temporary files now; they can't be referenced any 1661 // longer. 1662 llvm::sys::Path(astTmpFile).eraseFromDisk(); 1663 for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) 1664 TemporaryFiles[i].eraseFromDisk(); 1665 } 1666 1667 PTUI->result = ATU; 1668} 1669CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, 1670 const char *source_filename, 1671 const char **command_line_args, 1672 int num_command_line_args, 1673 struct CXUnsavedFile *unsaved_files, 1674 unsigned num_unsaved_files, 1675 unsigned options) { 1676 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args, 1677 num_command_line_args, unsaved_files, num_unsaved_files, 1678 options, 0 }; 1679 llvm::CrashRecoveryContext CRC; 1680 1681 if (!CRC.RunSafely(clang_parseTranslationUnit_Impl, &PTUI)) { 1682 fprintf(stderr, "libclang: crash detected during parsing: {\n"); 1683 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename); 1684 fprintf(stderr, " 'command_line_args' : ["); 1685 for (int i = 0; i != num_command_line_args; ++i) { 1686 if (i) 1687 fprintf(stderr, ", "); 1688 fprintf(stderr, "'%s'", command_line_args[i]); 1689 } 1690 fprintf(stderr, "],\n"); 1691 fprintf(stderr, " 'unsaved_files' : ["); 1692 for (unsigned i = 0; i != num_unsaved_files; ++i) { 1693 if (i) 1694 fprintf(stderr, ", "); 1695 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename, 1696 unsaved_files[i].Length); 1697 } 1698 fprintf(stderr, "],\n"); 1699 fprintf(stderr, " 'options' : %d,\n", options); 1700 fprintf(stderr, "}\n"); 1701 1702 return 0; 1703 } 1704 1705 return PTUI.result; 1706} 1707 1708unsigned clang_defaultSaveOptions(CXTranslationUnit TU) { 1709 return CXSaveTranslationUnit_None; 1710} 1711 1712int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName, 1713 unsigned options) { 1714 if (!TU) 1715 return 1; 1716 1717 return static_cast<ASTUnit *>(TU)->Save(FileName); 1718} 1719 1720void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { 1721 if (CTUnit) { 1722 // If the translation unit has been marked as unsafe to free, just discard 1723 // it. 1724 if (static_cast<ASTUnit *>(CTUnit)->isUnsafeToFree()) 1725 return; 1726 1727 delete static_cast<ASTUnit *>(CTUnit); 1728 } 1729} 1730 1731unsigned clang_defaultReparseOptions(CXTranslationUnit TU) { 1732 return CXReparse_None; 1733} 1734 1735struct ReparseTranslationUnitInfo { 1736 CXTranslationUnit TU; 1737 unsigned num_unsaved_files; 1738 struct CXUnsavedFile *unsaved_files; 1739 unsigned options; 1740 int result; 1741}; 1742static void clang_reparseTranslationUnit_Impl(void *UserData) { 1743 ReparseTranslationUnitInfo *RTUI = 1744 static_cast<ReparseTranslationUnitInfo*>(UserData); 1745 CXTranslationUnit TU = RTUI->TU; 1746 unsigned num_unsaved_files = RTUI->num_unsaved_files; 1747 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files; 1748 unsigned options = RTUI->options; 1749 (void) options; 1750 RTUI->result = 1; 1751 1752 if (!TU) 1753 return; 1754 1755 llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; 1756 for (unsigned I = 0; I != num_unsaved_files; ++I) { 1757 llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); 1758 const llvm::MemoryBuffer *Buffer 1759 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); 1760 RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, 1761 Buffer)); 1762 } 1763 1764 if (!static_cast<ASTUnit *>(TU)->Reparse(RemappedFiles.data(), 1765 RemappedFiles.size())) 1766 RTUI->result = 0; 1767} 1768int clang_reparseTranslationUnit(CXTranslationUnit TU, 1769 unsigned num_unsaved_files, 1770 struct CXUnsavedFile *unsaved_files, 1771 unsigned options) { 1772 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files, 1773 options, 0 }; 1774 llvm::CrashRecoveryContext CRC; 1775 1776 if (!CRC.RunSafely(clang_reparseTranslationUnit_Impl, &RTUI)) { 1777 fprintf(stderr, "libclang: crash detected during reparsing\n"); 1778 static_cast<ASTUnit *>(TU)->setUnsafeToFree(true); 1779 return 1; 1780 } 1781 1782 return RTUI.result; 1783} 1784 1785 1786CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) { 1787 if (!CTUnit) 1788 return createCXString(""); 1789 1790 ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit); 1791 return createCXString(CXXUnit->getOriginalSourceFileName(), true); 1792} 1793 1794CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) { 1795 CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } }; 1796 return Result; 1797} 1798 1799} // end: extern "C" 1800 1801//===----------------------------------------------------------------------===// 1802// CXSourceLocation and CXSourceRange Operations. 1803//===----------------------------------------------------------------------===// 1804 1805extern "C" { 1806CXSourceLocation clang_getNullLocation() { 1807 CXSourceLocation Result = { { 0, 0 }, 0 }; 1808 return Result; 1809} 1810 1811unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) { 1812 return (loc1.ptr_data[0] == loc2.ptr_data[0] && 1813 loc1.ptr_data[1] == loc2.ptr_data[1] && 1814 loc1.int_data == loc2.int_data); 1815} 1816 1817CXSourceLocation clang_getLocation(CXTranslationUnit tu, 1818 CXFile file, 1819 unsigned line, 1820 unsigned column) { 1821 if (!tu || !file) 1822 return clang_getNullLocation(); 1823 1824 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); 1825 SourceLocation SLoc 1826 = CXXUnit->getSourceManager().getLocation( 1827 static_cast<const FileEntry *>(file), 1828 line, column); 1829 1830 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); 1831} 1832 1833CXSourceRange clang_getNullRange() { 1834 CXSourceRange Result = { { 0, 0 }, 0, 0 }; 1835 return Result; 1836} 1837 1838CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) { 1839 if (begin.ptr_data[0] != end.ptr_data[0] || 1840 begin.ptr_data[1] != end.ptr_data[1]) 1841 return clang_getNullRange(); 1842 1843 CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] }, 1844 begin.int_data, end.int_data }; 1845 return Result; 1846} 1847 1848void clang_getInstantiationLocation(CXSourceLocation location, 1849 CXFile *file, 1850 unsigned *line, 1851 unsigned *column, 1852 unsigned *offset) { 1853 SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); 1854 1855 if (!location.ptr_data[0] || Loc.isInvalid()) { 1856 if (file) 1857 *file = 0; 1858 if (line) 1859 *line = 0; 1860 if (column) 1861 *column = 0; 1862 if (offset) 1863 *offset = 0; 1864 return; 1865 } 1866 1867 const SourceManager &SM = 1868 *static_cast<const SourceManager*>(location.ptr_data[0]); 1869 SourceLocation InstLoc = SM.getInstantiationLoc(Loc); 1870 1871 if (file) 1872 *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc)); 1873 if (line) 1874 *line = SM.getInstantiationLineNumber(InstLoc); 1875 if (column) 1876 *column = SM.getInstantiationColumnNumber(InstLoc); 1877 if (offset) 1878 *offset = SM.getDecomposedLoc(InstLoc).second; 1879} 1880 1881CXSourceLocation clang_getRangeStart(CXSourceRange range) { 1882 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, 1883 range.begin_int_data }; 1884 return Result; 1885} 1886 1887CXSourceLocation clang_getRangeEnd(CXSourceRange range) { 1888 CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, 1889 range.end_int_data }; 1890 return Result; 1891} 1892 1893} // end: extern "C" 1894 1895//===----------------------------------------------------------------------===// 1896// CXFile Operations. 1897//===----------------------------------------------------------------------===// 1898 1899extern "C" { 1900CXString clang_getFileName(CXFile SFile) { 1901 if (!SFile) 1902 return createCXString(NULL); 1903 1904 FileEntry *FEnt = static_cast<FileEntry *>(SFile); 1905 return createCXString(FEnt->getName()); 1906} 1907 1908time_t clang_getFileTime(CXFile SFile) { 1909 if (!SFile) 1910 return 0; 1911 1912 FileEntry *FEnt = static_cast<FileEntry *>(SFile); 1913 return FEnt->getModificationTime(); 1914} 1915 1916CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) { 1917 if (!tu) 1918 return 0; 1919 1920 ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); 1921 1922 FileManager &FMgr = CXXUnit->getFileManager(); 1923 const FileEntry *File = FMgr.getFile(file_name, file_name+strlen(file_name)); 1924 return const_cast<FileEntry *>(File); 1925} 1926 1927} // end: extern "C" 1928 1929//===----------------------------------------------------------------------===// 1930// CXCursor Operations. 1931//===----------------------------------------------------------------------===// 1932 1933static Decl *getDeclFromExpr(Stmt *E) { 1934 if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E)) 1935 return RefExpr->getDecl(); 1936 if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) 1937 return ME->getMemberDecl(); 1938 if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E)) 1939 return RE->getDecl(); 1940 1941 if (CallExpr *CE = dyn_cast<CallExpr>(E)) 1942 return getDeclFromExpr(CE->getCallee()); 1943 if (CastExpr *CE = dyn_cast<CastExpr>(E)) 1944 return getDeclFromExpr(CE->getSubExpr()); 1945 if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E)) 1946 return OME->getMethodDecl(); 1947 1948 return 0; 1949} 1950 1951static SourceLocation getLocationFromExpr(Expr *E) { 1952 if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) 1953 return /*FIXME:*/Msg->getLeftLoc(); 1954 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 1955 return DRE->getLocation(); 1956 if (MemberExpr *Member = dyn_cast<MemberExpr>(E)) 1957 return Member->getMemberLoc(); 1958 if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E)) 1959 return Ivar->getLocation(); 1960 return E->getLocStart(); 1961} 1962 1963extern "C" { 1964 1965unsigned clang_visitChildren(CXCursor parent, 1966 CXCursorVisitor visitor, 1967 CXClientData client_data) { 1968 ASTUnit *CXXUnit = getCursorASTUnit(parent); 1969 1970 CursorVisitor CursorVis(CXXUnit, visitor, client_data, 1971 CXXUnit->getMaxPCHLevel()); 1972 return CursorVis.VisitChildren(parent); 1973} 1974 1975static CXString getDeclSpelling(Decl *D) { 1976 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D); 1977 if (!ND) 1978 return createCXString(""); 1979 1980 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) 1981 return createCXString(OMD->getSelector().getAsString()); 1982 1983 if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND)) 1984 // No, this isn't the same as the code below. getIdentifier() is non-virtual 1985 // and returns different names. NamedDecl returns the class name and 1986 // ObjCCategoryImplDecl returns the category name. 1987 return createCXString(CIMP->getIdentifier()->getNameStart()); 1988 1989 llvm::SmallString<1024> S; 1990 llvm::raw_svector_ostream os(S); 1991 ND->printName(os); 1992 1993 return createCXString(os.str()); 1994} 1995 1996CXString clang_getCursorSpelling(CXCursor C) { 1997 if (clang_isTranslationUnit(C.kind)) 1998 return clang_getTranslationUnitSpelling(C.data[2]); 1999 2000 if (clang_isReference(C.kind)) { 2001 switch (C.kind) { 2002 case CXCursor_ObjCSuperClassRef: { 2003 ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first; 2004 return createCXString(Super->getIdentifier()->getNameStart()); 2005 } 2006 case CXCursor_ObjCClassRef: { 2007 ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; 2008 return createCXString(Class->getIdentifier()->getNameStart()); 2009 } 2010 case CXCursor_ObjCProtocolRef: { 2011 ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first; 2012 assert(OID && "getCursorSpelling(): Missing protocol decl"); 2013 return createCXString(OID->getIdentifier()->getNameStart()); 2014 } 2015 case CXCursor_CXXBaseSpecifier: { 2016 CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); 2017 return createCXString(B->getType().getAsString()); 2018 } 2019 case CXCursor_TypeRef: { 2020 TypeDecl *Type = getCursorTypeRef(C).first; 2021 assert(Type && "Missing type decl"); 2022 2023 return createCXString(getCursorContext(C).getTypeDeclType(Type). 2024 getAsString()); 2025 } 2026 2027 default: 2028 return createCXString("<not implemented>"); 2029 } 2030 } 2031 2032 if (clang_isExpression(C.kind)) { 2033 Decl *D = getDeclFromExpr(getCursorExpr(C)); 2034 if (D) 2035 return getDeclSpelling(D); 2036 return createCXString(""); 2037 } 2038 2039 if (C.kind == CXCursor_MacroInstantiation) 2040 return createCXString(getCursorMacroInstantiation(C)->getName() 2041 ->getNameStart()); 2042 2043 if (C.kind == CXCursor_MacroDefinition) 2044 return createCXString(getCursorMacroDefinition(C)->getName() 2045 ->getNameStart()); 2046 2047 if (clang_isDeclaration(C.kind)) 2048 return getDeclSpelling(getCursorDecl(C)); 2049 2050 return createCXString(""); 2051} 2052 2053CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { 2054 switch (Kind) { 2055 case CXCursor_FunctionDecl: 2056 return createCXString("FunctionDecl"); 2057 case CXCursor_TypedefDecl: 2058 return createCXString("TypedefDecl"); 2059 case CXCursor_EnumDecl: 2060 return createCXString("EnumDecl"); 2061 case CXCursor_EnumConstantDecl: 2062 return createCXString("EnumConstantDecl"); 2063 case CXCursor_StructDecl: 2064 return createCXString("StructDecl"); 2065 case CXCursor_UnionDecl: 2066 return createCXString("UnionDecl"); 2067 case CXCursor_ClassDecl: 2068 return createCXString("ClassDecl"); 2069 case CXCursor_FieldDecl: 2070 return createCXString("FieldDecl"); 2071 case CXCursor_VarDecl: 2072 return createCXString("VarDecl"); 2073 case CXCursor_ParmDecl: 2074 return createCXString("ParmDecl"); 2075 case CXCursor_ObjCInterfaceDecl: 2076 return createCXString("ObjCInterfaceDecl"); 2077 case CXCursor_ObjCCategoryDecl: 2078 return createCXString("ObjCCategoryDecl"); 2079 case CXCursor_ObjCProtocolDecl: 2080 return createCXString("ObjCProtocolDecl"); 2081 case CXCursor_ObjCPropertyDecl: 2082 return createCXString("ObjCPropertyDecl"); 2083 case CXCursor_ObjCIvarDecl: 2084 return createCXString("ObjCIvarDecl"); 2085 case CXCursor_ObjCInstanceMethodDecl: 2086 return createCXString("ObjCInstanceMethodDecl"); 2087 case CXCursor_ObjCClassMethodDecl: 2088 return createCXString("ObjCClassMethodDecl"); 2089 case CXCursor_ObjCImplementationDecl: 2090 return createCXString("ObjCImplementationDecl"); 2091 case CXCursor_ObjCCategoryImplDecl: 2092 return createCXString("ObjCCategoryImplDecl"); 2093 case CXCursor_CXXMethod: 2094 return createCXString("CXXMethod"); 2095 case CXCursor_UnexposedDecl: 2096 return createCXString("UnexposedDecl"); 2097 case CXCursor_ObjCSuperClassRef: 2098 return createCXString("ObjCSuperClassRef"); 2099 case CXCursor_ObjCProtocolRef: 2100 return createCXString("ObjCProtocolRef"); 2101 case CXCursor_ObjCClassRef: 2102 return createCXString("ObjCClassRef"); 2103 case CXCursor_TypeRef: 2104 return createCXString("TypeRef"); 2105 case CXCursor_UnexposedExpr: 2106 return createCXString("UnexposedExpr"); 2107 case CXCursor_BlockExpr: 2108 return createCXString("BlockExpr"); 2109 case CXCursor_DeclRefExpr: 2110 return createCXString("DeclRefExpr"); 2111 case CXCursor_MemberRefExpr: 2112 return createCXString("MemberRefExpr"); 2113 case CXCursor_CallExpr: 2114 return createCXString("CallExpr"); 2115 case CXCursor_ObjCMessageExpr: 2116 return createCXString("ObjCMessageExpr"); 2117 case CXCursor_UnexposedStmt: 2118 return createCXString("UnexposedStmt"); 2119 case CXCursor_InvalidFile: 2120 return createCXString("InvalidFile"); 2121 case CXCursor_InvalidCode: 2122 return createCXString("InvalidCode"); 2123 case CXCursor_NoDeclFound: 2124 return createCXString("NoDeclFound"); 2125 case CXCursor_NotImplemented: 2126 return createCXString("NotImplemented"); 2127 case CXCursor_TranslationUnit: 2128 return createCXString("TranslationUnit"); 2129 case CXCursor_UnexposedAttr: 2130 return createCXString("UnexposedAttr"); 2131 case CXCursor_IBActionAttr: 2132 return createCXString("attribute(ibaction)"); 2133 case CXCursor_IBOutletAttr: 2134 return createCXString("attribute(iboutlet)"); 2135 case CXCursor_IBOutletCollectionAttr: 2136 return createCXString("attribute(iboutletcollection)"); 2137 case CXCursor_PreprocessingDirective: 2138 return createCXString("preprocessing directive"); 2139 case CXCursor_MacroDefinition: 2140 return createCXString("macro definition"); 2141 case CXCursor_MacroInstantiation: 2142 return createCXString("macro instantiation"); 2143 case CXCursor_Namespace: 2144 return createCXString("Namespace"); 2145 case CXCursor_LinkageSpec: 2146 return createCXString("LinkageSpec"); 2147 case CXCursor_CXXBaseSpecifier: 2148 return createCXString("C++ base class specifier"); 2149 case CXCursor_Constructor: 2150 return createCXString("CXXConstructor"); 2151 case CXCursor_Destructor: 2152 return createCXString("CXXDestructor"); 2153 case CXCursor_ConversionFunction: 2154 return createCXString("CXXConversion"); 2155 case CXCursor_TemplateTypeParameter: 2156 return createCXString("TemplateTypeParameter"); 2157 case CXCursor_NonTypeTemplateParameter: 2158 return createCXString("NonTypeTemplateParameter"); 2159 case CXCursor_TemplateTemplateParameter: 2160 return createCXString("TemplateTemplateParameter"); 2161 case CXCursor_FunctionTemplate: 2162 return createCXString("FunctionTemplate"); 2163 case CXCursor_ClassTemplate: 2164 return createCXString("ClassTemplate"); 2165 case CXCursor_ClassTemplatePartialSpecialization: 2166 return createCXString("ClassTemplatePartialSpecialization"); 2167 } 2168 2169 llvm_unreachable("Unhandled CXCursorKind"); 2170 return createCXString(NULL); 2171} 2172 2173enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, 2174 CXCursor parent, 2175 CXClientData client_data) { 2176 CXCursor *BestCursor = static_cast<CXCursor *>(client_data); 2177 *BestCursor = cursor; 2178 return CXChildVisit_Recurse; 2179} 2180 2181CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { 2182 if (!TU) 2183 return clang_getNullCursor(); 2184 2185 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 2186 ASTUnit::ConcurrencyCheck Check(*CXXUnit); 2187 2188 // Translate the given source location to make it point at the beginning of 2189 // the token under the cursor. 2190 SourceLocation SLoc = cxloc::translateSourceLocation(Loc); 2191 2192 // Guard against an invalid SourceLocation, or we may assert in one 2193 // of the following calls. 2194 if (SLoc.isInvalid()) 2195 return clang_getNullCursor(); 2196 2197 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(), 2198 CXXUnit->getASTContext().getLangOptions()); 2199 2200 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound); 2201 if (SLoc.isValid()) { 2202 // FIXME: Would be great to have a "hint" cursor, then walk from that 2203 // hint cursor upward until we find a cursor whose source range encloses 2204 // the region of interest, rather than starting from the translation unit. 2205 CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit); 2206 CursorVisitor CursorVis(CXXUnit, GetCursorVisitor, &Result, 2207 Decl::MaxPCHLevel, SourceLocation(SLoc)); 2208 CursorVis.VisitChildren(Parent); 2209 } 2210 return Result; 2211} 2212 2213CXCursor clang_getNullCursor(void) { 2214 return MakeCXCursorInvalid(CXCursor_InvalidFile); 2215} 2216 2217unsigned clang_equalCursors(CXCursor X, CXCursor Y) { 2218 return X == Y; 2219} 2220 2221unsigned clang_isInvalid(enum CXCursorKind K) { 2222 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid; 2223} 2224 2225unsigned clang_isDeclaration(enum CXCursorKind K) { 2226 return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl; 2227} 2228 2229unsigned clang_isReference(enum CXCursorKind K) { 2230 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef; 2231} 2232 2233unsigned clang_isExpression(enum CXCursorKind K) { 2234 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr; 2235} 2236 2237unsigned clang_isStatement(enum CXCursorKind K) { 2238 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt; 2239} 2240 2241unsigned clang_isTranslationUnit(enum CXCursorKind K) { 2242 return K == CXCursor_TranslationUnit; 2243} 2244 2245unsigned clang_isPreprocessing(enum CXCursorKind K) { 2246 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing; 2247} 2248 2249unsigned clang_isUnexposed(enum CXCursorKind K) { 2250 switch (K) { 2251 case CXCursor_UnexposedDecl: 2252 case CXCursor_UnexposedExpr: 2253 case CXCursor_UnexposedStmt: 2254 case CXCursor_UnexposedAttr: 2255 return true; 2256 default: 2257 return false; 2258 } 2259} 2260 2261CXCursorKind clang_getCursorKind(CXCursor C) { 2262 return C.kind; 2263} 2264 2265CXSourceLocation clang_getCursorLocation(CXCursor C) { 2266 if (clang_isReference(C.kind)) { 2267 switch (C.kind) { 2268 case CXCursor_ObjCSuperClassRef: { 2269 std::pair<ObjCInterfaceDecl *, SourceLocation> P 2270 = getCursorObjCSuperClassRef(C); 2271 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 2272 } 2273 2274 case CXCursor_ObjCProtocolRef: { 2275 std::pair<ObjCProtocolDecl *, SourceLocation> P 2276 = getCursorObjCProtocolRef(C); 2277 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 2278 } 2279 2280 case CXCursor_ObjCClassRef: { 2281 std::pair<ObjCInterfaceDecl *, SourceLocation> P 2282 = getCursorObjCClassRef(C); 2283 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 2284 } 2285 2286 case CXCursor_TypeRef: { 2287 std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C); 2288 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 2289 } 2290 2291 case CXCursor_CXXBaseSpecifier: { 2292 // FIXME: Figure out what location to return for a CXXBaseSpecifier. 2293 return clang_getNullLocation(); 2294 } 2295 2296 default: 2297 // FIXME: Need a way to enumerate all non-reference cases. 2298 llvm_unreachable("Missed a reference kind"); 2299 } 2300 } 2301 2302 if (clang_isExpression(C.kind)) 2303 return cxloc::translateSourceLocation(getCursorContext(C), 2304 getLocationFromExpr(getCursorExpr(C))); 2305 2306 if (C.kind == CXCursor_PreprocessingDirective) { 2307 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin(); 2308 return cxloc::translateSourceLocation(getCursorContext(C), L); 2309 } 2310 2311 if (C.kind == CXCursor_MacroInstantiation) { 2312 SourceLocation L 2313 = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin(); 2314 return cxloc::translateSourceLocation(getCursorContext(C), L); 2315 } 2316 2317 if (C.kind == CXCursor_MacroDefinition) { 2318 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation(); 2319 return cxloc::translateSourceLocation(getCursorContext(C), L); 2320 } 2321 2322 if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl) 2323 return clang_getNullLocation(); 2324 2325 Decl *D = getCursorDecl(C); 2326 SourceLocation Loc = D->getLocation(); 2327 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D)) 2328 Loc = Class->getClassLoc(); 2329 return cxloc::translateSourceLocation(getCursorContext(C), Loc); 2330} 2331 2332} // end extern "C" 2333 2334static SourceRange getRawCursorExtent(CXCursor C) { 2335 if (clang_isReference(C.kind)) { 2336 switch (C.kind) { 2337 case CXCursor_ObjCSuperClassRef: 2338 return getCursorObjCSuperClassRef(C).second; 2339 2340 case CXCursor_ObjCProtocolRef: 2341 return getCursorObjCProtocolRef(C).second; 2342 2343 case CXCursor_ObjCClassRef: 2344 return getCursorObjCClassRef(C).second; 2345 2346 case CXCursor_TypeRef: 2347 return getCursorTypeRef(C).second; 2348 2349 case CXCursor_CXXBaseSpecifier: 2350 // FIXME: Figure out what source range to use for a CXBaseSpecifier. 2351 return SourceRange(); 2352 2353 default: 2354 // FIXME: Need a way to enumerate all non-reference cases. 2355 llvm_unreachable("Missed a reference kind"); 2356 } 2357 } 2358 2359 if (clang_isExpression(C.kind)) 2360 return getCursorExpr(C)->getSourceRange(); 2361 2362 if (clang_isStatement(C.kind)) 2363 return getCursorStmt(C)->getSourceRange(); 2364 2365 if (C.kind == CXCursor_PreprocessingDirective) 2366 return cxcursor::getCursorPreprocessingDirective(C); 2367 2368 if (C.kind == CXCursor_MacroInstantiation) 2369 return cxcursor::getCursorMacroInstantiation(C)->getSourceRange(); 2370 2371 if (C.kind == CXCursor_MacroDefinition) 2372 return cxcursor::getCursorMacroDefinition(C)->getSourceRange(); 2373 2374 if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) 2375 return getCursorDecl(C)->getSourceRange(); 2376 2377 return SourceRange(); 2378} 2379 2380extern "C" { 2381 2382CXSourceRange clang_getCursorExtent(CXCursor C) { 2383 SourceRange R = getRawCursorExtent(C); 2384 if (R.isInvalid()) 2385 return clang_getNullRange(); 2386 2387 return cxloc::translateSourceRange(getCursorContext(C), R); 2388} 2389 2390CXCursor clang_getCursorReferenced(CXCursor C) { 2391 if (clang_isInvalid(C.kind)) 2392 return clang_getNullCursor(); 2393 2394 ASTUnit *CXXUnit = getCursorASTUnit(C); 2395 if (clang_isDeclaration(C.kind)) 2396 return C; 2397 2398 if (clang_isExpression(C.kind)) { 2399 Decl *D = getDeclFromExpr(getCursorExpr(C)); 2400 if (D) 2401 return MakeCXCursor(D, CXXUnit); 2402 return clang_getNullCursor(); 2403 } 2404 2405 if (C.kind == CXCursor_MacroInstantiation) { 2406 if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition()) 2407 return MakeMacroDefinitionCursor(Def, CXXUnit); 2408 } 2409 2410 if (!clang_isReference(C.kind)) 2411 return clang_getNullCursor(); 2412 2413 switch (C.kind) { 2414 case CXCursor_ObjCSuperClassRef: 2415 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, CXXUnit); 2416 2417 case CXCursor_ObjCProtocolRef: { 2418 return MakeCXCursor(getCursorObjCProtocolRef(C).first, CXXUnit); 2419 2420 case CXCursor_ObjCClassRef: 2421 return MakeCXCursor(getCursorObjCClassRef(C).first, CXXUnit); 2422 2423 case CXCursor_TypeRef: 2424 return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit); 2425 2426 case CXCursor_CXXBaseSpecifier: { 2427 CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); 2428 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), 2429 CXXUnit)); 2430 } 2431 2432 default: 2433 // We would prefer to enumerate all non-reference cursor kinds here. 2434 llvm_unreachable("Unhandled reference cursor kind"); 2435 break; 2436 } 2437 } 2438 2439 return clang_getNullCursor(); 2440} 2441 2442CXCursor clang_getCursorDefinition(CXCursor C) { 2443 if (clang_isInvalid(C.kind)) 2444 return clang_getNullCursor(); 2445 2446 ASTUnit *CXXUnit = getCursorASTUnit(C); 2447 2448 bool WasReference = false; 2449 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) { 2450 C = clang_getCursorReferenced(C); 2451 WasReference = true; 2452 } 2453 2454 if (C.kind == CXCursor_MacroInstantiation) 2455 return clang_getCursorReferenced(C); 2456 2457 if (!clang_isDeclaration(C.kind)) 2458 return clang_getNullCursor(); 2459 2460 Decl *D = getCursorDecl(C); 2461 if (!D) 2462 return clang_getNullCursor(); 2463 2464 switch (D->getKind()) { 2465 // Declaration kinds that don't really separate the notions of 2466 // declaration and definition. 2467 case Decl::Namespace: 2468 case Decl::Typedef: 2469 case Decl::TemplateTypeParm: 2470 case Decl::EnumConstant: 2471 case Decl::Field: 2472 case Decl::ObjCIvar: 2473 case Decl::ObjCAtDefsField: 2474 case Decl::ImplicitParam: 2475 case Decl::ParmVar: 2476 case Decl::NonTypeTemplateParm: 2477 case Decl::TemplateTemplateParm: 2478 case Decl::ObjCCategoryImpl: 2479 case Decl::ObjCImplementation: 2480 case Decl::AccessSpec: 2481 case Decl::LinkageSpec: 2482 case Decl::ObjCPropertyImpl: 2483 case Decl::FileScopeAsm: 2484 case Decl::StaticAssert: 2485 case Decl::Block: 2486 return C; 2487 2488 // Declaration kinds that don't make any sense here, but are 2489 // nonetheless harmless. 2490 case Decl::TranslationUnit: 2491 break; 2492 2493 // Declaration kinds for which the definition is not resolvable. 2494 case Decl::UnresolvedUsingTypename: 2495 case Decl::UnresolvedUsingValue: 2496 break; 2497 2498 case Decl::UsingDirective: 2499 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(), 2500 CXXUnit); 2501 2502 case Decl::NamespaceAlias: 2503 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), CXXUnit); 2504 2505 case Decl::Enum: 2506 case Decl::Record: 2507 case Decl::CXXRecord: 2508 case Decl::ClassTemplateSpecialization: 2509 case Decl::ClassTemplatePartialSpecialization: 2510 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition()) 2511 return MakeCXCursor(Def, CXXUnit); 2512 return clang_getNullCursor(); 2513 2514 case Decl::Function: 2515 case Decl::CXXMethod: 2516 case Decl::CXXConstructor: 2517 case Decl::CXXDestructor: 2518 case Decl::CXXConversion: { 2519 const FunctionDecl *Def = 0; 2520 if (cast<FunctionDecl>(D)->getBody(Def)) 2521 return MakeCXCursor(const_cast<FunctionDecl *>(Def), CXXUnit); 2522 return clang_getNullCursor(); 2523 } 2524 2525 case Decl::Var: { 2526 // Ask the variable if it has a definition. 2527 if (VarDecl *Def = cast<VarDecl>(D)->getDefinition()) 2528 return MakeCXCursor(Def, CXXUnit); 2529 return clang_getNullCursor(); 2530 } 2531 2532 case Decl::FunctionTemplate: { 2533 const FunctionDecl *Def = 0; 2534 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def)) 2535 return MakeCXCursor(Def->getDescribedFunctionTemplate(), CXXUnit); 2536 return clang_getNullCursor(); 2537 } 2538 2539 case Decl::ClassTemplate: { 2540 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl() 2541 ->getDefinition()) 2542 return MakeCXCursor( 2543 cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(), 2544 CXXUnit); 2545 return clang_getNullCursor(); 2546 } 2547 2548 case Decl::Using: { 2549 UsingDecl *Using = cast<UsingDecl>(D); 2550 CXCursor Def = clang_getNullCursor(); 2551 for (UsingDecl::shadow_iterator S = Using->shadow_begin(), 2552 SEnd = Using->shadow_end(); 2553 S != SEnd; ++S) { 2554 if (Def != clang_getNullCursor()) { 2555 // FIXME: We have no way to return multiple results. 2556 return clang_getNullCursor(); 2557 } 2558 2559 Def = clang_getCursorDefinition(MakeCXCursor((*S)->getTargetDecl(), 2560 CXXUnit)); 2561 } 2562 2563 return Def; 2564 } 2565 2566 case Decl::UsingShadow: 2567 return clang_getCursorDefinition( 2568 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), 2569 CXXUnit)); 2570 2571 case Decl::ObjCMethod: { 2572 ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D); 2573 if (Method->isThisDeclarationADefinition()) 2574 return C; 2575 2576 // Dig out the method definition in the associated 2577 // @implementation, if we have it. 2578 // FIXME: The ASTs should make finding the definition easier. 2579 if (ObjCInterfaceDecl *Class 2580 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) 2581 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) 2582 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), 2583 Method->isInstanceMethod())) 2584 if (Def->isThisDeclarationADefinition()) 2585 return MakeCXCursor(Def, CXXUnit); 2586 2587 return clang_getNullCursor(); 2588 } 2589 2590 case Decl::ObjCCategory: 2591 if (ObjCCategoryImplDecl *Impl 2592 = cast<ObjCCategoryDecl>(D)->getImplementation()) 2593 return MakeCXCursor(Impl, CXXUnit); 2594 return clang_getNullCursor(); 2595 2596 case Decl::ObjCProtocol: 2597 if (!cast<ObjCProtocolDecl>(D)->isForwardDecl()) 2598 return C; 2599 return clang_getNullCursor(); 2600 2601 case Decl::ObjCInterface: 2602 // There are two notions of a "definition" for an Objective-C 2603 // class: the interface and its implementation. When we resolved a 2604 // reference to an Objective-C class, produce the @interface as 2605 // the definition; when we were provided with the interface, 2606 // produce the @implementation as the definition. 2607 if (WasReference) { 2608 if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl()) 2609 return C; 2610 } else if (ObjCImplementationDecl *Impl 2611 = cast<ObjCInterfaceDecl>(D)->getImplementation()) 2612 return MakeCXCursor(Impl, CXXUnit); 2613 return clang_getNullCursor(); 2614 2615 case Decl::ObjCProperty: 2616 // FIXME: We don't really know where to find the 2617 // ObjCPropertyImplDecls that implement this property. 2618 return clang_getNullCursor(); 2619 2620 case Decl::ObjCCompatibleAlias: 2621 if (ObjCInterfaceDecl *Class 2622 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface()) 2623 if (!Class->isForwardDecl()) 2624 return MakeCXCursor(Class, CXXUnit); 2625 2626 return clang_getNullCursor(); 2627 2628 case Decl::ObjCForwardProtocol: { 2629 ObjCForwardProtocolDecl *Forward = cast<ObjCForwardProtocolDecl>(D); 2630 if (Forward->protocol_size() == 1) 2631 return clang_getCursorDefinition( 2632 MakeCXCursor(*Forward->protocol_begin(), 2633 CXXUnit)); 2634 2635 // FIXME: Cannot return multiple definitions. 2636 return clang_getNullCursor(); 2637 } 2638 2639 case Decl::ObjCClass: { 2640 ObjCClassDecl *Class = cast<ObjCClassDecl>(D); 2641 if (Class->size() == 1) { 2642 ObjCInterfaceDecl *IFace = Class->begin()->getInterface(); 2643 if (!IFace->isForwardDecl()) 2644 return MakeCXCursor(IFace, CXXUnit); 2645 return clang_getNullCursor(); 2646 } 2647 2648 // FIXME: Cannot return multiple definitions. 2649 return clang_getNullCursor(); 2650 } 2651 2652 case Decl::Friend: 2653 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl()) 2654 return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit)); 2655 return clang_getNullCursor(); 2656 2657 case Decl::FriendTemplate: 2658 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl()) 2659 return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit)); 2660 return clang_getNullCursor(); 2661 } 2662 2663 return clang_getNullCursor(); 2664} 2665 2666unsigned clang_isCursorDefinition(CXCursor C) { 2667 if (!clang_isDeclaration(C.kind)) 2668 return 0; 2669 2670 return clang_getCursorDefinition(C) == C; 2671} 2672 2673void clang_getDefinitionSpellingAndExtent(CXCursor C, 2674 const char **startBuf, 2675 const char **endBuf, 2676 unsigned *startLine, 2677 unsigned *startColumn, 2678 unsigned *endLine, 2679 unsigned *endColumn) { 2680 assert(getCursorDecl(C) && "CXCursor has null decl"); 2681 NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C)); 2682 FunctionDecl *FD = dyn_cast<FunctionDecl>(ND); 2683 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody()); 2684 2685 SourceManager &SM = FD->getASTContext().getSourceManager(); 2686 *startBuf = SM.getCharacterData(Body->getLBracLoc()); 2687 *endBuf = SM.getCharacterData(Body->getRBracLoc()); 2688 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc()); 2689 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc()); 2690 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc()); 2691 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc()); 2692} 2693 2694void clang_enableStackTraces(void) { 2695 llvm::sys::PrintStackTraceOnErrorSignal(); 2696} 2697 2698} // end: extern "C" 2699 2700//===----------------------------------------------------------------------===// 2701// Token-based Operations. 2702//===----------------------------------------------------------------------===// 2703 2704/* CXToken layout: 2705 * int_data[0]: a CXTokenKind 2706 * int_data[1]: starting token location 2707 * int_data[2]: token length 2708 * int_data[3]: reserved 2709 * ptr_data: for identifiers and keywords, an IdentifierInfo*. 2710 * otherwise unused. 2711 */ 2712extern "C" { 2713 2714CXTokenKind clang_getTokenKind(CXToken CXTok) { 2715 return static_cast<CXTokenKind>(CXTok.int_data[0]); 2716} 2717 2718CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) { 2719 switch (clang_getTokenKind(CXTok)) { 2720 case CXToken_Identifier: 2721 case CXToken_Keyword: 2722 // We know we have an IdentifierInfo*, so use that. 2723 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data) 2724 ->getNameStart()); 2725 2726 case CXToken_Literal: { 2727 // We have stashed the starting pointer in the ptr_data field. Use it. 2728 const char *Text = static_cast<const char *>(CXTok.ptr_data); 2729 return createCXString(llvm::StringRef(Text, CXTok.int_data[2])); 2730 } 2731 2732 case CXToken_Punctuation: 2733 case CXToken_Comment: 2734 break; 2735 } 2736 2737 // We have to find the starting buffer pointer the hard way, by 2738 // deconstructing the source location. 2739 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 2740 if (!CXXUnit) 2741 return createCXString(""); 2742 2743 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); 2744 std::pair<FileID, unsigned> LocInfo 2745 = CXXUnit->getSourceManager().getDecomposedLoc(Loc); 2746 bool Invalid = false; 2747 llvm::StringRef Buffer 2748 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); 2749 if (Invalid) 2750 return createCXString(""); 2751 2752 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2])); 2753} 2754 2755CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) { 2756 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 2757 if (!CXXUnit) 2758 return clang_getNullLocation(); 2759 2760 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), 2761 SourceLocation::getFromRawEncoding(CXTok.int_data[1])); 2762} 2763 2764CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) { 2765 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 2766 if (!CXXUnit) 2767 return clang_getNullRange(); 2768 2769 return cxloc::translateSourceRange(CXXUnit->getASTContext(), 2770 SourceLocation::getFromRawEncoding(CXTok.int_data[1])); 2771} 2772 2773void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, 2774 CXToken **Tokens, unsigned *NumTokens) { 2775 if (Tokens) 2776 *Tokens = 0; 2777 if (NumTokens) 2778 *NumTokens = 0; 2779 2780 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 2781 if (!CXXUnit || !Tokens || !NumTokens) 2782 return; 2783 2784 ASTUnit::ConcurrencyCheck Check(*CXXUnit); 2785 2786 SourceRange R = cxloc::translateCXSourceRange(Range); 2787 if (R.isInvalid()) 2788 return; 2789 2790 SourceManager &SourceMgr = CXXUnit->getSourceManager(); 2791 std::pair<FileID, unsigned> BeginLocInfo 2792 = SourceMgr.getDecomposedLoc(R.getBegin()); 2793 std::pair<FileID, unsigned> EndLocInfo 2794 = SourceMgr.getDecomposedLoc(R.getEnd()); 2795 2796 // Cannot tokenize across files. 2797 if (BeginLocInfo.first != EndLocInfo.first) 2798 return; 2799 2800 // Create a lexer 2801 bool Invalid = false; 2802 llvm::StringRef Buffer 2803 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); 2804 if (Invalid) 2805 return; 2806 2807 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), 2808 CXXUnit->getASTContext().getLangOptions(), 2809 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end()); 2810 Lex.SetCommentRetentionState(true); 2811 2812 // Lex tokens until we hit the end of the range. 2813 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second; 2814 llvm::SmallVector<CXToken, 32> CXTokens; 2815 Token Tok; 2816 do { 2817 // Lex the next token 2818 Lex.LexFromRawLexer(Tok); 2819 if (Tok.is(tok::eof)) 2820 break; 2821 2822 // Initialize the CXToken. 2823 CXToken CXTok; 2824 2825 // - Common fields 2826 CXTok.int_data[1] = Tok.getLocation().getRawEncoding(); 2827 CXTok.int_data[2] = Tok.getLength(); 2828 CXTok.int_data[3] = 0; 2829 2830 // - Kind-specific fields 2831 if (Tok.isLiteral()) { 2832 CXTok.int_data[0] = CXToken_Literal; 2833 CXTok.ptr_data = (void *)Tok.getLiteralData(); 2834 } else if (Tok.is(tok::identifier)) { 2835 // Lookup the identifier to determine whether we have a keyword. 2836 std::pair<FileID, unsigned> LocInfo 2837 = SourceMgr.getDecomposedLoc(Tok.getLocation()); 2838 bool Invalid = false; 2839 llvm::StringRef Buf 2840 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); 2841 if (Invalid) 2842 return; 2843 2844 const char *StartPos = Buf.data() + LocInfo.second; 2845 IdentifierInfo *II 2846 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok, StartPos); 2847 2848 if (II->getObjCKeywordID() != tok::objc_not_keyword) { 2849 CXTok.int_data[0] = CXToken_Keyword; 2850 } 2851 else { 2852 CXTok.int_data[0] = II->getTokenID() == tok::identifier? 2853 CXToken_Identifier 2854 : CXToken_Keyword; 2855 } 2856 CXTok.ptr_data = II; 2857 } else if (Tok.is(tok::comment)) { 2858 CXTok.int_data[0] = CXToken_Comment; 2859 CXTok.ptr_data = 0; 2860 } else { 2861 CXTok.int_data[0] = CXToken_Punctuation; 2862 CXTok.ptr_data = 0; 2863 } 2864 CXTokens.push_back(CXTok); 2865 } while (Lex.getBufferLocation() <= EffectiveBufferEnd); 2866 2867 if (CXTokens.empty()) 2868 return; 2869 2870 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size()); 2871 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); 2872 *NumTokens = CXTokens.size(); 2873} 2874 2875void clang_disposeTokens(CXTranslationUnit TU, 2876 CXToken *Tokens, unsigned NumTokens) { 2877 free(Tokens); 2878} 2879 2880} // end: extern "C" 2881 2882//===----------------------------------------------------------------------===// 2883// Token annotation APIs. 2884//===----------------------------------------------------------------------===// 2885 2886typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData; 2887static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 2888 CXCursor parent, 2889 CXClientData client_data); 2890namespace { 2891class AnnotateTokensWorker { 2892 AnnotateTokensData &Annotated; 2893 CXToken *Tokens; 2894 CXCursor *Cursors; 2895 unsigned NumTokens; 2896 unsigned TokIdx; 2897 CursorVisitor AnnotateVis; 2898 SourceManager &SrcMgr; 2899 2900 bool MoreTokens() const { return TokIdx < NumTokens; } 2901 unsigned NextToken() const { return TokIdx; } 2902 void AdvanceToken() { ++TokIdx; } 2903 SourceLocation GetTokenLoc(unsigned tokI) { 2904 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]); 2905 } 2906 2907public: 2908 AnnotateTokensWorker(AnnotateTokensData &annotated, 2909 CXToken *tokens, CXCursor *cursors, unsigned numTokens, 2910 ASTUnit *CXXUnit, SourceRange RegionOfInterest) 2911 : Annotated(annotated), Tokens(tokens), Cursors(cursors), 2912 NumTokens(numTokens), TokIdx(0), 2913 AnnotateVis(CXXUnit, AnnotateTokensVisitor, this, 2914 Decl::MaxPCHLevel, RegionOfInterest), 2915 SrcMgr(CXXUnit->getSourceManager()) {} 2916 2917 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); } 2918 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent); 2919 void AnnotateTokens(CXCursor parent); 2920}; 2921} 2922 2923void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) { 2924 // Walk the AST within the region of interest, annotating tokens 2925 // along the way. 2926 VisitChildren(parent); 2927 2928 for (unsigned I = 0 ; I < TokIdx ; ++I) { 2929 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); 2930 if (Pos != Annotated.end()) 2931 Cursors[I] = Pos->second; 2932 } 2933 2934 // Finish up annotating any tokens left. 2935 if (!MoreTokens()) 2936 return; 2937 2938 const CXCursor &C = clang_getNullCursor(); 2939 for (unsigned I = TokIdx ; I < NumTokens ; ++I) { 2940 AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); 2941 Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second; 2942 } 2943} 2944 2945enum CXChildVisitResult 2946AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { 2947 CXSourceLocation Loc = clang_getCursorLocation(cursor); 2948 // We can always annotate a preprocessing directive/macro instantiation. 2949 if (clang_isPreprocessing(cursor.kind)) { 2950 Annotated[Loc.int_data] = cursor; 2951 return CXChildVisit_Recurse; 2952 } 2953 2954 SourceRange cursorRange = getRawCursorExtent(cursor); 2955 2956 if (cursorRange.isInvalid()) 2957 return CXChildVisit_Continue; 2958 2959 SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data); 2960 2961 // Adjust the annotated range based specific declarations. 2962 const enum CXCursorKind cursorK = clang_getCursorKind(cursor); 2963 if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) { 2964 Decl *D = cxcursor::getCursorDecl(cursor); 2965 // Don't visit synthesized ObjC methods, since they have no syntatic 2966 // representation in the source. 2967 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 2968 if (MD->isSynthesized()) 2969 return CXChildVisit_Continue; 2970 } 2971 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { 2972 if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) { 2973 TypeLoc TL = TI->getTypeLoc(); 2974 SourceLocation TLoc = TL.getSourceRange().getBegin(); 2975 if (TLoc.isValid() && 2976 SrcMgr.isBeforeInTranslationUnit(TLoc, L)) 2977 cursorRange.setBegin(TLoc); 2978 } 2979 } 2980 } 2981 2982 // If the location of the cursor occurs within a macro instantiation, record 2983 // the spelling location of the cursor in our annotation map. We can then 2984 // paper over the token labelings during a post-processing step to try and 2985 // get cursor mappings for tokens that are the *arguments* of a macro 2986 // instantiation. 2987 if (L.isMacroID()) { 2988 unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding(); 2989 // Only invalidate the old annotation if it isn't part of a preprocessing 2990 // directive. Here we assume that the default construction of CXCursor 2991 // results in CXCursor.kind being an initialized value (i.e., 0). If 2992 // this isn't the case, we can fix by doing lookup + insertion. 2993 2994 CXCursor &oldC = Annotated[rawEncoding]; 2995 if (!clang_isPreprocessing(oldC.kind)) 2996 oldC = cursor; 2997 } 2998 2999 const enum CXCursorKind K = clang_getCursorKind(parent); 3000 const CXCursor updateC = 3001 (clang_isInvalid(K) || K == CXCursor_TranslationUnit) 3002 ? clang_getNullCursor() : parent; 3003 3004 while (MoreTokens()) { 3005 const unsigned I = NextToken(); 3006 SourceLocation TokLoc = GetTokenLoc(I); 3007 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 3008 case RangeBefore: 3009 Cursors[I] = updateC; 3010 AdvanceToken(); 3011 continue; 3012 case RangeAfter: 3013 case RangeOverlap: 3014 break; 3015 } 3016 break; 3017 } 3018 3019 // Visit children to get their cursor information. 3020 const unsigned BeforeChildren = NextToken(); 3021 VisitChildren(cursor); 3022 const unsigned AfterChildren = NextToken(); 3023 3024 // Adjust 'Last' to the last token within the extent of the cursor. 3025 while (MoreTokens()) { 3026 const unsigned I = NextToken(); 3027 SourceLocation TokLoc = GetTokenLoc(I); 3028 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 3029 case RangeBefore: 3030 assert(0 && "Infeasible"); 3031 case RangeAfter: 3032 break; 3033 case RangeOverlap: 3034 Cursors[I] = updateC; 3035 AdvanceToken(); 3036 continue; 3037 } 3038 break; 3039 } 3040 const unsigned Last = NextToken(); 3041 3042 // Scan the tokens that are at the beginning of the cursor, but are not 3043 // capture by the child cursors. 3044 3045 // For AST elements within macros, rely on a post-annotate pass to 3046 // to correctly annotate the tokens with cursors. Otherwise we can 3047 // get confusing results of having tokens that map to cursors that really 3048 // are expanded by an instantiation. 3049 if (L.isMacroID()) 3050 cursor = clang_getNullCursor(); 3051 3052 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) { 3053 if (!clang_isInvalid(clang_getCursorKind(Cursors[I]))) 3054 break; 3055 Cursors[I] = cursor; 3056 } 3057 // Scan the tokens that are at the end of the cursor, but are not captured 3058 // but the child cursors. 3059 for (unsigned I = AfterChildren; I != Last; ++I) 3060 Cursors[I] = cursor; 3061 3062 TokIdx = Last; 3063 return CXChildVisit_Continue; 3064} 3065 3066static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 3067 CXCursor parent, 3068 CXClientData client_data) { 3069 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent); 3070} 3071 3072extern "C" { 3073 3074void clang_annotateTokens(CXTranslationUnit TU, 3075 CXToken *Tokens, unsigned NumTokens, 3076 CXCursor *Cursors) { 3077 3078 if (NumTokens == 0 || !Tokens || !Cursors) 3079 return; 3080 3081 ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 3082 if (!CXXUnit) { 3083 // Any token we don't specifically annotate will have a NULL cursor. 3084 const CXCursor &C = clang_getNullCursor(); 3085 for (unsigned I = 0; I != NumTokens; ++I) 3086 Cursors[I] = C; 3087 return; 3088 } 3089 3090 ASTUnit::ConcurrencyCheck Check(*CXXUnit); 3091 3092 // Determine the region of interest, which contains all of the tokens. 3093 SourceRange RegionOfInterest; 3094 RegionOfInterest.setBegin(cxloc::translateSourceLocation( 3095 clang_getTokenLocation(TU, Tokens[0]))); 3096 RegionOfInterest.setEnd(cxloc::translateSourceLocation( 3097 clang_getTokenLocation(TU, 3098 Tokens[NumTokens - 1]))); 3099 3100 // A mapping from the source locations found when re-lexing or traversing the 3101 // region of interest to the corresponding cursors. 3102 AnnotateTokensData Annotated; 3103 3104 // Relex the tokens within the source range to look for preprocessing 3105 // directives. 3106 SourceManager &SourceMgr = CXXUnit->getSourceManager(); 3107 std::pair<FileID, unsigned> BeginLocInfo 3108 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin()); 3109 std::pair<FileID, unsigned> EndLocInfo 3110 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd()); 3111 3112 llvm::StringRef Buffer; 3113 bool Invalid = false; 3114 if (BeginLocInfo.first == EndLocInfo.first && 3115 ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) && 3116 !Invalid) { 3117 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), 3118 CXXUnit->getASTContext().getLangOptions(), 3119 Buffer.begin(), Buffer.data() + BeginLocInfo.second, 3120 Buffer.end()); 3121 Lex.SetCommentRetentionState(true); 3122 3123 // Lex tokens in raw mode until we hit the end of the range, to avoid 3124 // entering #includes or expanding macros. 3125 while (true) { 3126 Token Tok; 3127 Lex.LexFromRawLexer(Tok); 3128 3129 reprocess: 3130 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) { 3131 // We have found a preprocessing directive. Gobble it up so that we 3132 // don't see it while preprocessing these tokens later, but keep track of 3133 // all of the token locations inside this preprocessing directive so that 3134 // we can annotate them appropriately. 3135 // 3136 // FIXME: Some simple tests here could identify macro definitions and 3137 // #undefs, to provide specific cursor kinds for those. 3138 std::vector<SourceLocation> Locations; 3139 do { 3140 Locations.push_back(Tok.getLocation()); 3141 Lex.LexFromRawLexer(Tok); 3142 } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof)); 3143 3144 using namespace cxcursor; 3145 CXCursor Cursor 3146 = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(), 3147 Locations.back()), 3148 CXXUnit); 3149 for (unsigned I = 0, N = Locations.size(); I != N; ++I) { 3150 Annotated[Locations[I].getRawEncoding()] = Cursor; 3151 } 3152 3153 if (Tok.isAtStartOfLine()) 3154 goto reprocess; 3155 3156 continue; 3157 } 3158 3159 if (Tok.is(tok::eof)) 3160 break; 3161 } 3162 } 3163 3164 // Annotate all of the source locations in the region of interest that map to 3165 // a specific cursor. 3166 AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens, 3167 CXXUnit, RegionOfInterest); 3168 W.AnnotateTokens(clang_getTranslationUnitCursor(CXXUnit)); 3169} 3170} // end: extern "C" 3171 3172//===----------------------------------------------------------------------===// 3173// Operations for querying linkage of a cursor. 3174//===----------------------------------------------------------------------===// 3175 3176extern "C" { 3177CXLinkageKind clang_getCursorLinkage(CXCursor cursor) { 3178 if (!clang_isDeclaration(cursor.kind)) 3179 return CXLinkage_Invalid; 3180 3181 Decl *D = cxcursor::getCursorDecl(cursor); 3182 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) 3183 switch (ND->getLinkage()) { 3184 case NoLinkage: return CXLinkage_NoLinkage; 3185 case InternalLinkage: return CXLinkage_Internal; 3186 case UniqueExternalLinkage: return CXLinkage_UniqueExternal; 3187 case ExternalLinkage: return CXLinkage_External; 3188 }; 3189 3190 return CXLinkage_Invalid; 3191} 3192} // end: extern "C" 3193 3194//===----------------------------------------------------------------------===// 3195// Operations for querying language of a cursor. 3196//===----------------------------------------------------------------------===// 3197 3198static CXLanguageKind getDeclLanguage(const Decl *D) { 3199 switch (D->getKind()) { 3200 default: 3201 break; 3202 case Decl::ImplicitParam: 3203 case Decl::ObjCAtDefsField: 3204 case Decl::ObjCCategory: 3205 case Decl::ObjCCategoryImpl: 3206 case Decl::ObjCClass: 3207 case Decl::ObjCCompatibleAlias: 3208 case Decl::ObjCForwardProtocol: 3209 case Decl::ObjCImplementation: 3210 case Decl::ObjCInterface: 3211 case Decl::ObjCIvar: 3212 case Decl::ObjCMethod: 3213 case Decl::ObjCProperty: 3214 case Decl::ObjCPropertyImpl: 3215 case Decl::ObjCProtocol: 3216 return CXLanguage_ObjC; 3217 case Decl::CXXConstructor: 3218 case Decl::CXXConversion: 3219 case Decl::CXXDestructor: 3220 case Decl::CXXMethod: 3221 case Decl::CXXRecord: 3222 case Decl::ClassTemplate: 3223 case Decl::ClassTemplatePartialSpecialization: 3224 case Decl::ClassTemplateSpecialization: 3225 case Decl::Friend: 3226 case Decl::FriendTemplate: 3227 case Decl::FunctionTemplate: 3228 case Decl::LinkageSpec: 3229 case Decl::Namespace: 3230 case Decl::NamespaceAlias: 3231 case Decl::NonTypeTemplateParm: 3232 case Decl::StaticAssert: 3233 case Decl::TemplateTemplateParm: 3234 case Decl::TemplateTypeParm: 3235 case Decl::UnresolvedUsingTypename: 3236 case Decl::UnresolvedUsingValue: 3237 case Decl::Using: 3238 case Decl::UsingDirective: 3239 case Decl::UsingShadow: 3240 return CXLanguage_CPlusPlus; 3241 } 3242 3243 return CXLanguage_C; 3244} 3245 3246extern "C" { 3247 3248enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) { 3249 if (clang_isDeclaration(cursor.kind)) 3250 if (Decl *D = cxcursor::getCursorDecl(cursor)) { 3251 if (D->hasAttr<UnavailableAttr>() || 3252 (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())) 3253 return CXAvailability_Available; 3254 3255 if (D->hasAttr<DeprecatedAttr>()) 3256 return CXAvailability_Deprecated; 3257 } 3258 3259 return CXAvailability_Available; 3260} 3261 3262CXLanguageKind clang_getCursorLanguage(CXCursor cursor) { 3263 if (clang_isDeclaration(cursor.kind)) 3264 return getDeclLanguage(cxcursor::getCursorDecl(cursor)); 3265 3266 return CXLanguage_Invalid; 3267} 3268} // end: extern "C" 3269 3270 3271//===----------------------------------------------------------------------===// 3272// C++ AST instrospection. 3273//===----------------------------------------------------------------------===// 3274 3275extern "C" { 3276unsigned clang_CXXMethod_isStatic(CXCursor C) { 3277 if (!clang_isDeclaration(C.kind)) 3278 return 0; 3279 CXXMethodDecl *D = dyn_cast<CXXMethodDecl>(cxcursor::getCursorDecl(C)); 3280 return (D && D->isStatic()) ? 1 : 0; 3281} 3282 3283} // end: extern "C" 3284 3285//===----------------------------------------------------------------------===// 3286// Attribute introspection. 3287//===----------------------------------------------------------------------===// 3288 3289extern "C" { 3290CXType clang_getIBOutletCollectionType(CXCursor C) { 3291 if (C.kind != CXCursor_IBOutletCollectionAttr) 3292 return cxtype::MakeCXType(QualType(), cxcursor::getCursorASTUnit(C)); 3293 3294 IBOutletCollectionAttr *A = 3295 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C)); 3296 3297 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorASTUnit(C)); 3298} 3299} // end: extern "C" 3300 3301//===----------------------------------------------------------------------===// 3302// CXString Operations. 3303//===----------------------------------------------------------------------===// 3304 3305extern "C" { 3306const char *clang_getCString(CXString string) { 3307 return string.Spelling; 3308} 3309 3310void clang_disposeString(CXString string) { 3311 if (string.MustFreeString && string.Spelling) 3312 free((void*)string.Spelling); 3313} 3314 3315} // end: extern "C" 3316 3317namespace clang { namespace cxstring { 3318CXString createCXString(const char *String, bool DupString){ 3319 CXString Str; 3320 if (DupString) { 3321 Str.Spelling = strdup(String); 3322 Str.MustFreeString = 1; 3323 } else { 3324 Str.Spelling = String; 3325 Str.MustFreeString = 0; 3326 } 3327 return Str; 3328} 3329 3330CXString createCXString(llvm::StringRef String, bool DupString) { 3331 CXString Result; 3332 if (DupString || (!String.empty() && String.data()[String.size()] != 0)) { 3333 char *Spelling = (char *)malloc(String.size() + 1); 3334 memmove(Spelling, String.data(), String.size()); 3335 Spelling[String.size()] = 0; 3336 Result.Spelling = Spelling; 3337 Result.MustFreeString = 1; 3338 } else { 3339 Result.Spelling = String.data(); 3340 Result.MustFreeString = 0; 3341 } 3342 return Result; 3343} 3344}} 3345 3346//===----------------------------------------------------------------------===// 3347// Misc. utility functions. 3348//===----------------------------------------------------------------------===// 3349 3350extern "C" { 3351 3352CXString clang_getClangVersion() { 3353 return createCXString(getClangFullVersion()); 3354} 3355 3356} // end: extern "C" 3357